@tui-sandbox/library 7.7.0 → 8.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tui-sandbox/library",
3
- "version": "7.7.0",
3
+ "version": "8.0.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,36 +15,39 @@ if (!app) {
15
15
 
16
16
  const client = new TerminalClient(app)
17
17
 
18
+ export type GenericNeovimBrowserApi = {
19
+ runBlockingShellCommand(input: BlockingCommandClientInput): Promise<BlockingShellCommandOutput>
20
+ runLuaCode(input: LuaCodeClientInput): Promise<RunLuaCodeOutput>
21
+ runExCommand(input: ExCommandClientInput): Promise<RunExCommandOutput>
22
+ dir: TestDirectory
23
+ }
24
+
18
25
  /** Entrypoint for the test runner (cypress) */
19
- window.startNeovim = async function (startArgs?: StartNeovimGenericArguments): Promise<TestDirectory> {
26
+ window.startNeovim = async function (startArgs?: StartNeovimGenericArguments): Promise<GenericNeovimBrowserApi> {
20
27
  const testDirectory = await client.startNeovim({
21
28
  additionalEnvironmentVariables: startArgs?.additionalEnvironmentVariables,
22
29
  filename: startArgs?.filename ?? "initial-file.txt",
23
30
  startupScriptModifications: startArgs?.startupScriptModifications ?? [],
24
31
  })
25
32
 
26
- return testDirectory
27
- }
28
-
29
- window.runBlockingShellCommand = async function (
30
- input: BlockingCommandClientInput
31
- ): Promise<BlockingShellCommandOutput> {
32
- return client.runBlockingShellCommand(input)
33
- }
34
-
35
- window.runLuaCode = async function (input: LuaCodeClientInput): Promise<RunLuaCodeOutput> {
36
- return client.runLuaCode(input)
37
- }
33
+ const neovimBrowserApi: GenericNeovimBrowserApi = {
34
+ runBlockingShellCommand(input: BlockingCommandClientInput): Promise<BlockingShellCommandOutput> {
35
+ return client.runBlockingShellCommand(input)
36
+ },
37
+ runLuaCode(input) {
38
+ return client.runLuaCode(input)
39
+ },
40
+ runExCommand(input) {
41
+ return client.runExCommand(input)
42
+ },
43
+ dir: testDirectory,
44
+ }
38
45
 
39
- window.runExCommand = async function (input: ExCommandClientInput): Promise<RunExCommandOutput> {
40
- return client.runExCommand(input)
46
+ return neovimBrowserApi
41
47
  }
42
48
 
43
49
  declare global {
44
50
  interface Window {
45
- startNeovim(startArguments?: StartNeovimGenericArguments): Promise<TestDirectory>
46
- runBlockingShellCommand(input: BlockingCommandClientInput): Promise<BlockingShellCommandOutput>
47
- runLuaCode(input: LuaCodeClientInput): Promise<RunLuaCodeOutput>
48
- runExCommand(input: ExCommandClientInput): Promise<RunExCommandOutput>
51
+ startNeovim(startArguments?: StartNeovimGenericArguments): Promise<GenericNeovimBrowserApi>
49
52
  }
50
53
  }
@@ -23,17 +23,30 @@ import type {
23
23
  TestDirectory,
24
24
  } from "@tui-sandbox/library/dist/src/server/types"
25
25
  import type { OverrideProperties } from "type-fest"
26
+ import type { GenericNeovimBrowserApi } from "../../../library/src/browser/neovim-client.ts"
26
27
  import type { MyTestDirectory, MyTestDirectoryFile } from "../../MyTestDirectory"
27
28
 
28
- export type NeovimContext = TestDirectory<MyTestDirectory>
29
+ /** The api that can be used in tests after a Neovim instance has been started. */
30
+ export type NeovimContext = {
31
+ /** Types text into the terminal, making the terminal application receive
32
+ * the keystrokes as input. Requires neovim to be running. */
33
+ typeIntoTerminal(text: string, options?: Partial<Cypress.TypeOptions>): void
29
34
 
30
- declare global {
31
- interface Window {
32
- startNeovim(startArguments?: MyStartNeovimServerArguments): Promise<NeovimContext>
33
- runBlockingShellCommand(input: BlockingCommandClientInput): Promise<BlockingShellCommandOutput>
34
- runLuaCode(input: LuaCodeClientInput): Promise<RunLuaCodeOutput>
35
- runExCommand(input: ExCommandClientInput): Promise<RunExCommandOutput>
36
- }
35
+ /** Runs a shell command in a blocking manner, waiting for the command to
36
+ * finish before returning. Requires neovim to be running. */
37
+ runBlockingShellCommand(input: BlockingCommandClientInput): Cypress.Chainable<BlockingShellCommandOutput>
38
+
39
+ /** Runs a shell command in a blocking manner, waiting for the command to
40
+ * finish before returning. Requires neovim to be running. */
41
+ runLuaCode(input: LuaCodeClientInput): Cypress.Chainable<RunLuaCodeOutput>
42
+
43
+ /** Run an ex command in neovim.
44
+ * @example "echo expand('%:.')" current file, relative to the cwd
45
+ */
46
+ runExCommand(input: ExCommandClientInput): Cypress.Chainable<RunExCommandOutput>
47
+
48
+ /** The test directory, providing type-safe access to its file and directory structure */
49
+ dir: TestDirectory<MyTestDirectory>
37
50
  }
38
51
 
39
52
  /** Arguments for starting the neovim server. They are built based on your test
@@ -42,21 +55,41 @@ type MyStartNeovimServerArguments = OverrideProperties<
42
55
  StartNeovimGenericArguments,
43
56
  {
44
57
  filename?: MyTestDirectoryFile | { openInVerticalSplits: MyTestDirectoryFile[] }
45
- // NOTE: right now you need to make sure the config-modifications directory exists in your test directory
46
58
  startupScriptModifications?: Array<keyof MyTestDirectory["config-modifications"]["contents"]>
47
59
  }
48
60
  >
49
61
 
50
62
  Cypress.Commands.add("startNeovim", (startArguments?: MyStartNeovimServerArguments) => {
51
63
  cy.window().then(async win => {
52
- testWindow = win
53
- return await win.startNeovim(startArguments)
54
- })
55
- })
64
+ const underlyingNeovim: GenericNeovimBrowserApi = await win.startNeovim(
65
+ startArguments as StartNeovimGenericArguments
66
+ )
67
+ testNeovim = underlyingNeovim
68
+
69
+ // wrap everything so that Cypress can await all the commands
70
+ Cypress.Commands.addAll({
71
+ nvim_runBlockingShellCommand: underlyingNeovim.runBlockingShellCommand,
72
+ nvim_runExCommand: underlyingNeovim.runExCommand,
73
+ nvim_runLuaCode: underlyingNeovim.runLuaCode,
74
+ })
75
+
76
+ const api: NeovimContext = {
77
+ runBlockingShellCommand(input) {
78
+ return cy.nvim_runBlockingShellCommand(input)
79
+ },
80
+ runExCommand(input) {
81
+ return cy.nvim_runExCommand(input)
82
+ },
83
+ runLuaCode(input) {
84
+ return cy.nvim_runLuaCode(input)
85
+ },
86
+ typeIntoTerminal(text, options) {
87
+ cy.typeIntoTerminal(text, options)
88
+ },
89
+ dir: underlyingNeovim.dir as TestDirectory<MyTestDirectory>,
90
+ }
56
91
 
57
- Cypress.Commands.add("runBlockingShellCommand", (input: BlockingCommandClientInput) => {
58
- cy.window().then(async win => {
59
- return await win.runBlockingShellCommand(input)
92
+ return api
60
93
  })
61
94
  })
62
95
 
@@ -66,19 +99,7 @@ Cypress.Commands.add("typeIntoTerminal", (text: string, options?: Partial<Cypres
66
99
  cy.get("textarea").focus().type(text, options)
67
100
  })
68
101
 
69
- Cypress.Commands.add("runLuaCode", (input: LuaCodeClientInput) => {
70
- cy.window().then(async win => {
71
- return await win.runLuaCode(input)
72
- })
73
- })
74
-
75
- Cypress.Commands.add("runExCommand", (input: ExCommandClientInput) => {
76
- cy.window().then(async win => {
77
- return await win.runExCommand(input)
78
- })
79
- })
80
-
81
- let testWindow: Window | undefined
102
+ let testNeovim: GenericNeovimBrowserApi | undefined
82
103
 
83
104
  before(function () {
84
105
  // disable Cypress's default behavior of logging all XMLHttpRequests and
@@ -98,28 +119,34 @@ declare global {
98
119
 
99
120
  /** Runs a shell command in a blocking manner, waiting for the command to
100
121
  * finish before returning. Requires neovim to be running. */
101
- runBlockingShellCommand(input: BlockingCommandClientInput): Chainable<BlockingShellCommandOutput>
122
+ nvim_runBlockingShellCommand(input: BlockingCommandClientInput): Chainable<BlockingShellCommandOutput>
102
123
 
103
- runLuaCode(input: LuaCodeClientInput): Chainable<RunLuaCodeOutput>
124
+ nvim_runLuaCode(input: LuaCodeClientInput): Chainable<RunLuaCodeOutput>
104
125
 
105
126
  /** Run an ex command in neovim.
106
127
  * @example "echo expand('%:.')" current file, relative to the cwd
107
128
  */
108
- runExCommand(input: ExCommandClientInput): Chainable<RunExCommandOutput>
129
+ nvim_runExCommand(input: ExCommandClientInput): Chainable<RunExCommandOutput>
109
130
  }
110
131
  }
111
132
  }
112
133
 
113
134
  afterEach(async () => {
114
- if (!testWindow) return
115
- const timeout = new Promise<void>((resolve, reject) =>
116
- setTimeout(() => {
117
- Cypress.log({ name: "timeout when waiting for :messages to finish. Neovim might be stuck." })
118
- reject("timeout when waiting for :messages to finish. Neovim might be stuck.")
135
+ if (!testNeovim) return
136
+
137
+ let timeoutId: NodeJS.Timeout | undefined = undefined
138
+ const timeout = new Promise<void>((_, reject) => {
139
+ timeoutId = setTimeout(() => {
140
+ Cypress.log({ name: "timeout when waiting for :messages to finish. Neovim might be stuck or showing a message." })
141
+ reject(new Error("timeout when waiting for :messages to finish. Neovim might be stuck or showing a message."))
119
142
  }, 5_000)
120
- )
143
+ })
121
144
 
122
- await Promise.race([timeout, testWindow.runExCommand({ command: "messages" })])
145
+ try {
146
+ await Promise.race([timeout, testNeovim.runExCommand({ command: "messages" })])
147
+ } finally {
148
+ clearTimeout(timeoutId) // Ensure the timeout is cleared
149
+ }
123
150
  })
124
151
  `
125
152