-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from vim-denops/stub
👍 Add `DenopsStub` class to stub denops for tests.
- Loading branch information
Showing
9 changed files
with
564 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,29 @@ | ||
import * as path from "https://deno.land/std@0.187.0/path/mod.ts"; | ||
import * as path from "https://deno.land/std@0.190.0/path/mod.ts"; | ||
import { orElse } from "./or_else.ts"; | ||
|
||
function get(name: string): string | undefined { | ||
return Deno.env.get(`DENOPS_TEST_${name}`); | ||
} | ||
let conf: Config | undefined; | ||
|
||
/** Absolute local path of denops added to Vim runtimepath */ | ||
export const DENOPS_PATH = path.resolve( | ||
orElse(get("DENOPS_PATH"), () => { | ||
throw new Error( | ||
"Environment variable 'DENOPS_TEST_DENOPS_PATH' is required", | ||
); | ||
}), | ||
); | ||
export type Config = { | ||
denopsPath: string; | ||
vimExecutable: string; | ||
nvimExecutable: string; | ||
}; | ||
|
||
/** Executable name of Vim */ | ||
export const VIM_EXECUTABLE = get("VIM_EXECUTABLE") ?? "vim"; | ||
export function getConfig(): Config { | ||
if (!conf) { | ||
conf = { | ||
denopsPath: path.resolve(orElse(get("DENOPS_PATH"), () => { | ||
throw new Error( | ||
"Environment variable 'DENOPS_TEST_DENOPS_PATH' is required", | ||
); | ||
})), | ||
vimExecutable: get("VIM_EXECUTABLE") ?? "vim", | ||
nvimExecutable: get("NVIM_EXECUTABLE") ?? "nvim", | ||
}; | ||
} | ||
return conf; | ||
} | ||
|
||
/** Executable name of Neovim */ | ||
export const NVIM_EXECUTABLE = get("NVIM_EXECUTABLE") ?? "nvim"; | ||
function get(name: string): string | undefined { | ||
return Deno.env.get(`DENOPS_TEST_${name}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
import { | ||
Context, | ||
Denops, | ||
Dispatcher, | ||
Meta, | ||
} from "https://deno.land/x/[email protected]/mod.ts"; | ||
|
||
/** | ||
* Represents a `Denops` stubber object. | ||
*/ | ||
export type DenopsStubber = { | ||
/** | ||
* Denops instance name whihc uses to communicate with vim. | ||
* | ||
* If not specified, the default value is `denops-test-stub`. | ||
*/ | ||
name?: string; | ||
/** | ||
* Environment meta information. | ||
* | ||
* If not specified, the default value is: | ||
* ```json | ||
* { | ||
* "mode": "release", | ||
* "host": "vim", | ||
* "version": "0.0.0", | ||
* "platform": "linux" | ||
* } | ||
* ``` | ||
*/ | ||
meta?: Meta; | ||
/** | ||
* A stub function of `redraw` method of the `Denops`. | ||
* | ||
* If not specified, it returns a promise resolves to undefined. | ||
*/ | ||
redraw?: (force?: boolean) => Promise<void>; | ||
/** | ||
* A stub function of `call` method of the `Denops`. | ||
* | ||
* If not specified, it returns a promise resolves to undefined. | ||
*/ | ||
call?(fn: string, ...args: unknown[]): Promise<unknown>; | ||
/** | ||
* A stub function of `batch` method of the `Denops`. | ||
* | ||
* If not specified, it returns a promise resolves to an empty list. | ||
*/ | ||
batch?(...calls: [string, ...unknown[]][]): Promise<unknown[]>; | ||
/** | ||
* A stub function of `cmd` method of the `Denops`. | ||
* | ||
* If not specified, it returns a promise resolves to undefined. | ||
*/ | ||
cmd?(cmd: string, ctx: Context): Promise<void>; | ||
/** | ||
* A stub function of `eval` method of the `Denops`. | ||
* | ||
* If not specified, it returns a promise resolves to undefined. | ||
*/ | ||
eval?(expr: string, ctx: Context): Promise<unknown>; | ||
/** | ||
* A stub function of `dispatch` method of the `Denops`. | ||
* | ||
* If not specified, it returns a promise resolves to undefined. | ||
*/ | ||
dispatch?(name: string, fn: string, ...args: unknown[]): Promise<unknown>; | ||
/** | ||
* Indicates whether to use `call` function in `batch` method. | ||
*/ | ||
useCallInBatch?: boolean; | ||
/** | ||
* Indicates whether to use `call` function in `cmd` method. | ||
*/ | ||
useCallInCmd?: boolean; | ||
/** | ||
* Indicates whether to use `call` function in `eval` method. | ||
*/ | ||
useCallInEval?: boolean; | ||
}; | ||
|
||
/** | ||
* Represents a `Denops` stub object. | ||
*/ | ||
export class DenopsStub implements Denops { | ||
readonly context: Record<string | number | symbol, unknown> = {}; | ||
dispatcher: Dispatcher = {}; | ||
|
||
#stubber: DenopsStubber; | ||
|
||
/** | ||
* Creates a new instance of DenopsStub. | ||
* @param stubber - The Denops stubber object. | ||
*/ | ||
constructor(stubber: DenopsStubber = {}) { | ||
this.#stubber = stubber; | ||
} | ||
|
||
get name(): string { | ||
return this.#stubber.name ?? "denops-test-stub"; | ||
} | ||
|
||
get meta(): Meta { | ||
return this.#stubber.meta ?? { | ||
mode: "release", | ||
host: "vim", | ||
version: "0.0.0", | ||
platform: "linux", | ||
}; | ||
} | ||
|
||
redraw(force?: boolean): Promise<void> { | ||
if (this.#stubber.redraw) { | ||
return this.#stubber.redraw(force); | ||
} | ||
return Promise.resolve(); | ||
} | ||
|
||
call(fn: string, ...args: unknown[]): Promise<unknown> { | ||
if (this.#stubber.call) { | ||
args = normArgs(args); | ||
return this.#stubber.call(fn, ...args); | ||
} | ||
return Promise.resolve(); | ||
} | ||
|
||
batch(...calls: [string, ...unknown[]][]): Promise<unknown[]> { | ||
if (this.#stubber.batch) { | ||
calls = calls.map(([fn, ...args]) => [fn, ...normArgs(args)]); | ||
return this.#stubber.batch(...calls); | ||
} | ||
if (this.#stubber.call && this.#stubber.useCallInBatch) { | ||
return Promise.all( | ||
calls.map(([fn, ...args]) => this.call(fn, ...args)), | ||
); | ||
} | ||
return Promise.resolve(calls.map(() => undefined)); | ||
} | ||
|
||
cmd(cmd: string, ctx: Context = {}): Promise<void> { | ||
if (this.#stubber.cmd) { | ||
return this.#stubber.cmd(cmd, ctx); | ||
} | ||
if (this.#stubber.call && this.#stubber.useCallInCmd) { | ||
return this.call("denops#api#cmd", cmd, ctx).then(() => {}); | ||
} | ||
return Promise.resolve(); | ||
} | ||
|
||
eval(expr: string, ctx: Context = {}): Promise<unknown> { | ||
if (this.#stubber.eval) { | ||
return this.#stubber.eval(expr, ctx); | ||
} | ||
if (this.#stubber.call && this.#stubber.useCallInEval) { | ||
return this.call("denops#api#eval", expr, ctx); | ||
} | ||
return Promise.resolve(); | ||
} | ||
|
||
dispatch( | ||
name: string, | ||
fn: string, | ||
...args: unknown[] | ||
): Promise<unknown> { | ||
if (this.#stubber.dispatch) { | ||
return this.#stubber.dispatch(name, fn, ...args); | ||
} | ||
return Promise.resolve(); | ||
} | ||
} | ||
|
||
function normArgs(args: unknown[]): unknown[] { | ||
const normArgs = []; | ||
for (const arg of args) { | ||
if (arg === undefined) { | ||
break; | ||
} | ||
normArgs.push(arg); | ||
} | ||
return normArgs; | ||
} |
Oops, something went wrong.