@tui-sandbox/library 7.3.0 → 7.5.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/CHANGELOG.md +14 -0
- package/dist/browser/assets/{index-DUKWG3jG.js → index-CWXBquay.js} +7 -7
- package/dist/browser/index.html +1 -1
- package/dist/src/client/terminal-client.js +3 -12
- package/dist/src/scripts/tui.js +8 -5
- package/dist/src/server/cypress-support/contents.js +14 -4
- package/dist/src/server/cypress-support/contents.test.js +14 -4
- package/dist/src/server/neovim/environment/createTempDir.d.ts +2 -2
- package/dist/src/server/neovim/index.d.ts +3 -3
- package/dist/src/server/neovim/index.js +3 -0
- package/dist/src/server/server.d.ts +6 -2
- package/dist/src/server/server.js +7 -3
- package/dist/src/server/types.d.ts +2 -2
- package/dist/src/server/updateTestdirectorySchemaFile.d.ts +6 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -11
- package/src/client/terminal-client.ts +3 -12
- package/src/scripts/tui.ts +8 -5
- package/src/server/cypress-support/contents.test.ts +14 -4
- package/src/server/cypress-support/contents.ts +14 -4
- package/src/server/neovim/environment/createTempDir.ts +2 -2
- package/src/server/neovim/index.ts +6 -3
- package/src/server/server.ts +9 -5
- package/src/server/types.ts +2 -2
- package/src/server/updateTestdirectorySchemaFile.ts +7 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tui-sandbox/library",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@catppuccin/palette": "1.7.1",
|
|
11
|
-
"@trpc/client": "11.0.0-rc.
|
|
12
|
-
"@trpc/server": "11.0.0-rc.
|
|
11
|
+
"@trpc/client": "11.0.0-rc.666",
|
|
12
|
+
"@trpc/server": "11.0.0-rc.666",
|
|
13
13
|
"@xterm/addon-attach": "0.11.0",
|
|
14
14
|
"@xterm/addon-fit": "0.10.0",
|
|
15
15
|
"@xterm/xterm": "5.5.0",
|
|
@@ -17,24 +17,24 @@
|
|
|
17
17
|
"core-js": "3.39.0",
|
|
18
18
|
"cors": "2.8.5",
|
|
19
19
|
"dree": "5.1.5",
|
|
20
|
-
"express": "4.21.
|
|
20
|
+
"express": "4.21.2",
|
|
21
21
|
"neovim": "5.3.0",
|
|
22
22
|
"node-pty": "1.0.0",
|
|
23
|
-
"prettier": "3.4.
|
|
23
|
+
"prettier": "3.4.2",
|
|
24
24
|
"tsx": "4.19.2",
|
|
25
|
-
"type-fest": "4.
|
|
25
|
+
"type-fest": "4.30.2",
|
|
26
26
|
"winston": "3.17.0",
|
|
27
|
-
"zod": "3.
|
|
27
|
+
"zod": "3.24.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@runtyping/zod": "2.1.1",
|
|
31
31
|
"@types/command-exists": "1.2.3",
|
|
32
32
|
"@types/cors": "2.8.17",
|
|
33
33
|
"@types/express": "5.0.0",
|
|
34
|
-
"@types/node": "22.10.
|
|
35
|
-
"nodemon": "3.1.
|
|
36
|
-
"vite": "6.0.
|
|
37
|
-
"vitest": "2.1.
|
|
34
|
+
"@types/node": "22.10.2",
|
|
35
|
+
"nodemon": "3.1.9",
|
|
36
|
+
"vite": "6.0.5",
|
|
37
|
+
"vitest": "2.1.8"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"cypress": "^13",
|
|
@@ -98,25 +98,16 @@ export class TerminalClient {
|
|
|
98
98
|
|
|
99
99
|
public async runBlockingShellCommand(input: BlockingCommandClientInput): Promise<BlockingShellCommandOutput> {
|
|
100
100
|
await this.ready
|
|
101
|
-
return this.trpc.neovim.runBlockingShellCommand.mutate({
|
|
102
|
-
...input,
|
|
103
|
-
tabId: this.tabId,
|
|
104
|
-
})
|
|
101
|
+
return this.trpc.neovim.runBlockingShellCommand.mutate({ ...input, tabId: this.tabId })
|
|
105
102
|
}
|
|
106
103
|
|
|
107
104
|
public async runLuaCode(input: LuaCodeClientInput): Promise<RunLuaCodeOutput> {
|
|
108
105
|
await this.ready
|
|
109
|
-
return this.trpc.neovim.runLuaCode.mutate({
|
|
110
|
-
luaCode: input.luaCode,
|
|
111
|
-
tabId: this.tabId,
|
|
112
|
-
})
|
|
106
|
+
return this.trpc.neovim.runLuaCode.mutate({ ...input, tabId: this.tabId })
|
|
113
107
|
}
|
|
114
108
|
|
|
115
109
|
public async runExCommand(input: ExCommandClientInput): Promise<RunExCommandOutput> {
|
|
116
110
|
await this.ready
|
|
117
|
-
return this.trpc.neovim.runExCommand.mutate({
|
|
118
|
-
command: input.command,
|
|
119
|
-
tabId: this.tabId,
|
|
120
|
-
})
|
|
111
|
+
return this.trpc.neovim.runExCommand.mutate({ ...input, tabId: this.tabId })
|
|
121
112
|
}
|
|
122
113
|
}
|
package/src/scripts/tui.ts
CHANGED
|
@@ -18,8 +18,11 @@ const outputFileName = "MyTestDirectory.ts"
|
|
|
18
18
|
* cwd of the script itself. */
|
|
19
19
|
const cwd = process.cwd()
|
|
20
20
|
const config = {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
directories: {
|
|
22
|
+
testEnvironmentPath: path.join(cwd, "test-environment/"),
|
|
23
|
+
outputFilePath: path.join(cwd, outputFileName),
|
|
24
|
+
},
|
|
25
|
+
port: process.env["PORT"] ? parseInt(process.env["PORT"]) : 3000,
|
|
23
26
|
} satisfies TestServerConfig
|
|
24
27
|
|
|
25
28
|
// the arguments passed to this script start at index 2
|
|
@@ -35,11 +38,11 @@ if (args[0] === "neovim") {
|
|
|
35
38
|
|
|
36
39
|
{
|
|
37
40
|
// automatically dispose of the neovim instance when done
|
|
38
|
-
await using app = new NeovimApplication(config.testEnvironmentPath)
|
|
41
|
+
await using app = new NeovimApplication(config.directories.testEnvironmentPath)
|
|
39
42
|
app.events.on("stdout" satisfies StdoutOrStderrMessage, data => {
|
|
40
43
|
console.log(` neovim output: ${data}`)
|
|
41
44
|
})
|
|
42
|
-
const testDirectory = await prepareNewTestDirectory(config)
|
|
45
|
+
const testDirectory = await prepareNewTestDirectory(config.directories)
|
|
43
46
|
await app.startNextAndKillCurrent(
|
|
44
47
|
testDirectory,
|
|
45
48
|
{ filename: "empty.txt", headlessCmd: command },
|
|
@@ -62,7 +65,7 @@ try {
|
|
|
62
65
|
cypressSupportDirectoryPath: path.join(cwd, "cypress", "support"),
|
|
63
66
|
supportFileName: "tui-sandbox.ts",
|
|
64
67
|
})
|
|
65
|
-
await updateTestdirectorySchemaFile(config)
|
|
68
|
+
await updateTestdirectorySchemaFile(config.directories)
|
|
66
69
|
await startTestServer(config)
|
|
67
70
|
} catch (e) {
|
|
68
71
|
console.error(e)
|
|
@@ -17,14 +17,13 @@ it("should return the expected contents", async () => {
|
|
|
17
17
|
RunExCommandOutput,
|
|
18
18
|
RunLuaCodeOutput,
|
|
19
19
|
StartNeovimGenericArguments,
|
|
20
|
+
TestDirectory,
|
|
20
21
|
} from "@tui-sandbox/library/dist/src/server/types"
|
|
22
|
+
import assert from "assert"
|
|
21
23
|
import type { OverrideProperties } from "type-fest"
|
|
22
24
|
import type { MyTestDirectory, MyTestDirectoryFile } from "../../MyTestDirectory"
|
|
23
25
|
|
|
24
|
-
export type NeovimContext =
|
|
25
|
-
contents: MyTestDirectory
|
|
26
|
-
rootPathAbsolute: string
|
|
27
|
-
}
|
|
26
|
+
export type NeovimContext = TestDirectory<MyTestDirectory>
|
|
28
27
|
|
|
29
28
|
declare global {
|
|
30
29
|
interface Window {
|
|
@@ -46,6 +45,7 @@ it("should return the expected contents", async () => {
|
|
|
46
45
|
|
|
47
46
|
Cypress.Commands.add("startNeovim", (startArguments?: MyStartNeovimServerArguments) => {
|
|
48
47
|
cy.window().then(async win => {
|
|
48
|
+
testWindow = win
|
|
49
49
|
return await win.startNeovim(startArguments)
|
|
50
50
|
})
|
|
51
51
|
})
|
|
@@ -74,6 +74,13 @@ it("should return the expected contents", async () => {
|
|
|
74
74
|
})
|
|
75
75
|
})
|
|
76
76
|
|
|
77
|
+
let testWindow: Window | undefined
|
|
78
|
+
|
|
79
|
+
Cypress.on("fail", async () => {
|
|
80
|
+
assert(testWindow, "testWindow is not defined")
|
|
81
|
+
await testWindow.runExCommand({ command: "messages", log: true })
|
|
82
|
+
})
|
|
83
|
+
|
|
77
84
|
before(function () {
|
|
78
85
|
// disable Cypress's default behavior of logging all XMLHttpRequests and
|
|
79
86
|
// fetches to the Command Log
|
|
@@ -96,6 +103,9 @@ it("should return the expected contents", async () => {
|
|
|
96
103
|
|
|
97
104
|
runLuaCode(input: LuaCodeClientInput): Chainable<RunLuaCodeOutput>
|
|
98
105
|
|
|
106
|
+
/** Run an ex command in neovim.
|
|
107
|
+
* @example "echo expand('%:.')" current file, relative to the cwd
|
|
108
|
+
*/
|
|
99
109
|
runExCommand(input: ExCommandClientInput): Chainable<RunExCommandOutput>
|
|
100
110
|
}
|
|
101
111
|
}
|
|
@@ -20,14 +20,13 @@ import type {
|
|
|
20
20
|
RunExCommandOutput,
|
|
21
21
|
RunLuaCodeOutput,
|
|
22
22
|
StartNeovimGenericArguments,
|
|
23
|
+
TestDirectory,
|
|
23
24
|
} from "@tui-sandbox/library/dist/src/server/types"
|
|
25
|
+
import assert from "assert"
|
|
24
26
|
import type { OverrideProperties } from "type-fest"
|
|
25
27
|
import type { MyTestDirectory, MyTestDirectoryFile } from "../../MyTestDirectory"
|
|
26
28
|
|
|
27
|
-
export type NeovimContext =
|
|
28
|
-
contents: MyTestDirectory
|
|
29
|
-
rootPathAbsolute: string
|
|
30
|
-
}
|
|
29
|
+
export type NeovimContext = TestDirectory<MyTestDirectory>
|
|
31
30
|
|
|
32
31
|
declare global {
|
|
33
32
|
interface Window {
|
|
@@ -49,6 +48,7 @@ type MyStartNeovimServerArguments = OverrideProperties<
|
|
|
49
48
|
|
|
50
49
|
Cypress.Commands.add("startNeovim", (startArguments?: MyStartNeovimServerArguments) => {
|
|
51
50
|
cy.window().then(async win => {
|
|
51
|
+
testWindow = win
|
|
52
52
|
return await win.startNeovim(startArguments)
|
|
53
53
|
})
|
|
54
54
|
})
|
|
@@ -77,6 +77,13 @@ Cypress.Commands.add("runExCommand", (input: ExCommandClientInput) => {
|
|
|
77
77
|
})
|
|
78
78
|
})
|
|
79
79
|
|
|
80
|
+
let testWindow: Window | undefined
|
|
81
|
+
|
|
82
|
+
Cypress.on("fail", async () => {
|
|
83
|
+
assert(testWindow, "testWindow is not defined")
|
|
84
|
+
await testWindow.runExCommand({ command: "messages", log: true })
|
|
85
|
+
})
|
|
86
|
+
|
|
80
87
|
before(function () {
|
|
81
88
|
// disable Cypress's default behavior of logging all XMLHttpRequests and
|
|
82
89
|
// fetches to the Command Log
|
|
@@ -99,6 +106,9 @@ declare global {
|
|
|
99
106
|
|
|
100
107
|
runLuaCode(input: LuaCodeClientInput): Chainable<RunLuaCodeOutput>
|
|
101
108
|
|
|
109
|
+
/** Run an ex command in neovim.
|
|
110
|
+
* @example "echo expand('%:.')" current file, relative to the cwd
|
|
111
|
+
*/
|
|
102
112
|
runExCommand(input: ExCommandClientInput): Chainable<RunExCommandOutput>
|
|
103
113
|
}
|
|
104
114
|
}
|
|
@@ -6,10 +6,10 @@ import { access, mkdir, mkdtemp } from "fs/promises"
|
|
|
6
6
|
import path from "path"
|
|
7
7
|
import { convertDree, getDirectoryTree } from "../../dirtree/index.js"
|
|
8
8
|
import type { TestDirectory } from "../../types.js"
|
|
9
|
-
import type {
|
|
9
|
+
import type { DirectoriesConfig } from "../../updateTestdirectorySchemaFile.js"
|
|
10
10
|
import { updateTestdirectorySchemaFile } from "../../updateTestdirectorySchemaFile.js"
|
|
11
11
|
|
|
12
|
-
export async function createTempDir(config:
|
|
12
|
+
export async function createTempDir(config: DirectoriesConfig): Promise<TestDirectory> {
|
|
13
13
|
try {
|
|
14
14
|
const dir = await createUniqueDirectory(config.testEnvironmentPath)
|
|
15
15
|
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
StartNeovimGenericArguments,
|
|
11
11
|
TestDirectory,
|
|
12
12
|
} from "../types.js"
|
|
13
|
-
import type {
|
|
13
|
+
import type { DirectoriesConfig } from "../updateTestdirectorySchemaFile.js"
|
|
14
14
|
import { convertEventEmitterToAsyncGenerator } from "../utilities/generator.js"
|
|
15
15
|
import { Lazy } from "../utilities/Lazy.js"
|
|
16
16
|
import type { TabId } from "../utilities/tabId.js"
|
|
@@ -53,7 +53,7 @@ export async function start(
|
|
|
53
53
|
options: StartNeovimGenericArguments,
|
|
54
54
|
terminalDimensions: TerminalDimensions,
|
|
55
55
|
tabId: TabId,
|
|
56
|
-
config:
|
|
56
|
+
config: DirectoriesConfig
|
|
57
57
|
): Promise<TestDirectory> {
|
|
58
58
|
const neovim = neovims.get(tabId.tabId)
|
|
59
59
|
assert(neovim, `Neovim instance not found for client id ${tabId.tabId}`)
|
|
@@ -64,7 +64,7 @@ export async function start(
|
|
|
64
64
|
return testDirectory
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
export async function prepareNewTestDirectory(config:
|
|
67
|
+
export async function prepareNewTestDirectory(config: DirectoriesConfig): Promise<TestDirectory> {
|
|
68
68
|
await removeTestDirectories(config.testEnvironmentPath)
|
|
69
69
|
const testDirectory = await createTempDir(config)
|
|
70
70
|
return testDirectory
|
|
@@ -174,6 +174,9 @@ export async function runExCommand(options: ExCommandInput): Promise<RunExComman
|
|
|
174
174
|
console.log(`Neovim ${neovim.application.processId()} running Ex command: ${options.command}`)
|
|
175
175
|
try {
|
|
176
176
|
const output = await api.commandOutput(options.command)
|
|
177
|
+
if (options.log) {
|
|
178
|
+
console.log(`Ex command output: ${output}`)
|
|
179
|
+
}
|
|
177
180
|
return { value: output }
|
|
178
181
|
} catch (e) {
|
|
179
182
|
console.warn(`Error running Ex command: ${options.command}`, e)
|
package/src/server/server.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { z } from "zod"
|
|
|
5
5
|
import { trpc } from "./connection/trpc.js"
|
|
6
6
|
import * as neovim from "./neovim/index.js"
|
|
7
7
|
import { TestServer } from "./TestServer.js"
|
|
8
|
-
import type { TestServerConfig } from "./updateTestdirectorySchemaFile.js"
|
|
8
|
+
import type { DirectoriesConfig, TestServerConfig } from "./updateTestdirectorySchemaFile.js"
|
|
9
9
|
import { applicationAvailable } from "./utilities/applicationAvailable.js"
|
|
10
10
|
import { tabIdSchema } from "./utilities/tabId.js"
|
|
11
11
|
|
|
@@ -29,13 +29,17 @@ const luaCodeInputSchema = z.object({ tabId: tabIdSchema, luaCode: z.string() })
|
|
|
29
29
|
export type LuaCodeClientInput = Except<LuaCodeInput, "tabId">
|
|
30
30
|
export type LuaCodeInput = z.infer<typeof luaCodeInputSchema>
|
|
31
31
|
|
|
32
|
-
const exCommandInputSchema = z.object({
|
|
32
|
+
const exCommandInputSchema = z.object({
|
|
33
|
+
tabId: tabIdSchema,
|
|
34
|
+
command: z.string(),
|
|
35
|
+
log: z.boolean().optional(),
|
|
36
|
+
})
|
|
33
37
|
export type ExCommandClientInput = Except<ExCommandInput, "tabId">
|
|
34
38
|
export type ExCommandInput = z.infer<typeof exCommandInputSchema>
|
|
35
39
|
|
|
36
40
|
/** @private */
|
|
37
41
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
38
|
-
export async function createAppRouter(config:
|
|
42
|
+
export async function createAppRouter(config: DirectoriesConfig) {
|
|
39
43
|
if (!(await applicationAvailable("nvim"))) {
|
|
40
44
|
throw new Error("Neovim is not installed. Please install Neovim (nvim).")
|
|
41
45
|
}
|
|
@@ -99,9 +103,9 @@ export type RouterInput = inferRouterInputs<AppRouter>
|
|
|
99
103
|
|
|
100
104
|
export async function startTestServer(config: TestServerConfig): Promise<TestServer> {
|
|
101
105
|
const testServer = new TestServer({
|
|
102
|
-
port:
|
|
106
|
+
port: config.port,
|
|
103
107
|
})
|
|
104
|
-
const appRouter = await createAppRouter(config)
|
|
108
|
+
const appRouter = await createAppRouter(config.directories)
|
|
105
109
|
await testServer.startAndRun(appRouter)
|
|
106
110
|
|
|
107
111
|
return testServer
|
package/src/server/types.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { VimValue } from "neovim/lib/types/VimValue.js"
|
|
|
8
8
|
* be written with confidence that the files and directories they expect are
|
|
9
9
|
* actually found. Otherwise the tests are brittle and can break easily.
|
|
10
10
|
*/
|
|
11
|
-
export type TestDirectory = {
|
|
11
|
+
export type TestDirectory<TContents extends object = object> = {
|
|
12
12
|
/** The path to the unique test directory (the root).
|
|
13
13
|
*
|
|
14
14
|
* @example /Users/mikavilpas/git/tui-sandbox/packages/integration-tests/test-environment/testdirs/dir-0199UZ
|
|
@@ -28,7 +28,7 @@ export type TestDirectory = {
|
|
|
28
28
|
*/
|
|
29
29
|
testEnvironmentPathRelative: string
|
|
30
30
|
|
|
31
|
-
contents:
|
|
31
|
+
contents: TContents
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export type { StartNeovimGenericArguments } from "../server/neovim/NeovimApplication.js"
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync } from "fs"
|
|
2
2
|
import { buildTestDirectorySchema } from "./dirtree/index.js"
|
|
3
3
|
|
|
4
|
-
export type
|
|
4
|
+
export type DirectoriesConfig = {
|
|
5
5
|
testEnvironmentPath: string
|
|
6
6
|
outputFilePath: string
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
export type TestServerConfig = {
|
|
10
|
+
directories: DirectoriesConfig
|
|
11
|
+
port: number
|
|
12
|
+
}
|
|
13
|
+
|
|
9
14
|
export type UpdateTestdirectorySchemaFileResult = "updated" | "did-nothing"
|
|
10
15
|
|
|
11
16
|
export async function updateTestdirectorySchemaFile({
|
|
12
17
|
testEnvironmentPath,
|
|
13
18
|
outputFilePath,
|
|
14
|
-
}:
|
|
19
|
+
}: DirectoriesConfig): Promise<UpdateTestdirectorySchemaFileResult> {
|
|
15
20
|
const newSchema: string = await buildTestDirectorySchema(testEnvironmentPath)
|
|
16
21
|
let oldSchema = ""
|
|
17
22
|
|