@lvce-editor/shared-process 0.0.2 → 0.0.6

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.
Files changed (56) hide show
  1. package/config/builtinCommands.json +367 -0
  2. package/config/colorTheme.json +98 -0
  3. package/config/defaultKeyBindings.json +649 -0
  4. package/config/defaultSettings.json +17 -0
  5. package/extensions/builtin.theme-slime/README.md +5 -0
  6. package/extensions/builtin.theme-slime/color-theme.json +205 -0
  7. package/extensions/builtin.theme-slime/extension.json +13 -0
  8. package/extensions/builtin.theme-slime/icon.png +0 -0
  9. package/package.json +3 -3
  10. package/src/parts/Env/Env.js +1 -1
  11. package/src/parts/Platform/Platform.js +7 -0
  12. package/src/parts/Preferences/Preferences.js +3 -6
  13. package/src/parts/Root/Root.js +1 -1
  14. package/test/Callback.test.js +0 -42
  15. package/test/ClipBoard.test.js +0 -105
  16. package/test/Credentials.test.js +0 -147
  17. package/test/Developer.test.js +0 -34
  18. package/test/Electron.test.js +0 -93
  19. package/test/Error.test.js +0 -16
  20. package/test/Exec.test.js +0 -25
  21. package/test/ExtensionHost.test.js +0 -127
  22. package/test/ExtensionHostColorTheme.test.js +0 -141
  23. package/test/ExtensionHostCommand.test.js +0 -27
  24. package/test/ExtensionHostCompletion.test.js +0 -45
  25. package/test/ExtensionHostDefinition.test.js +0 -35
  26. package/test/ExtensionHostDiagnostic.test.js +0 -23
  27. package/test/ExtensionHostFileSystem.test.js +0 -91
  28. package/test/ExtensionHostFormatting.test.js +0 -27
  29. package/test/ExtensionHostIconTheme.test.js +0 -73
  30. package/test/ExtensionHostLanguages.test.js +0 -212
  31. package/test/ExtensionHostOutput.test.js +0 -23
  32. package/test/ExtensionHostRename.test.js +0 -59
  33. package/test/ExtensionHostSemanticTokens.test.js +0 -26
  34. package/test/ExtensionHostTabCompletion.test.js +0 -35
  35. package/test/ExtensionHostTextDocument.test.js +0 -61
  36. package/test/ExtensionHostTypeDefinition.test.js +0 -35
  37. package/test/ExtensionHostWorkspace.test.js +0 -21
  38. package/test/ExtensionManagement.test.js +0 -408
  39. package/test/FileSystem.test.js +0 -294
  40. package/test/Json.test.js +0 -25
  41. package/test/Native.test.js +0 -31
  42. package/test/OutputChannel.test.js +0 -68
  43. package/test/Path.test.js +0 -17
  44. package/test/Platform.test.js +0 -61
  45. package/test/Preferences.test.js +0 -140
  46. package/test/Process.test.js +0 -9
  47. package/test/RgPath.test.js +0 -5
  48. package/test/Search.test.js +0 -45
  49. package/test/SearchFile.test.js +0 -80
  50. package/test/Terminal.test.js +0 -53
  51. package/test/Trash.test.js +0 -34
  52. package/test/WebSocketServer.test.js +0 -98
  53. package/test/fixture-search-1/index.html +0 -10
  54. package/test/fixture-search-file-1/fileA +0 -0
  55. package/test/fixture-search-file-1/fileB +0 -0
  56. package/test/fixture-search-file-1/nested/fileC +0 -0
package/test/Json.test.js DELETED
@@ -1,25 +0,0 @@
1
- import * as Json from '../src/parts/Json/Json.js'
2
-
3
- test('parse', async () => {
4
- expect(await Json.parse('{ "x": 42 }')).toEqual({ x: 42 })
5
- })
6
-
7
- test('parse - syntax error', async () => {
8
- await expect(
9
- Json.parse('{ "x" 42 }', '/test/some-file.txt')
10
- ).rejects.toThrowError(
11
- /^Unexpected number in JSON at position 6 while parsing/
12
- )
13
- })
14
-
15
- test('stringify', () => {
16
- expect(Json.stringify({ x: 42 })).toBe(`{
17
- "x": 42
18
- }
19
- `)
20
- })
21
-
22
- test('stringify - invalid parameter', () => {
23
- expect(Json.stringify(Symbol('a'))).toBe(`undefined
24
- `)
25
- })
@@ -1,31 +0,0 @@
1
- import { jest } from '@jest/globals'
2
-
3
- jest.unstable_mockModule('open', () => {
4
- return {
5
- default: jest.fn(() => {
6
- throw new Error('not implemented')
7
- }),
8
- }
9
- })
10
-
11
- const open = await import('open')
12
- const Native = await import('../src/parts/Native/Native.js')
13
-
14
- test('openFolder', async () => {
15
- // @ts-ignore
16
- open.default.mockImplementation(() => {})
17
- await Native.openFolder('/test')
18
- expect(open.default).toHaveBeenCalledTimes(1)
19
- expect(open.default).toHaveBeenCalledWith('/test')
20
- })
21
-
22
- test('openFolder - error', async () => {
23
- // @ts-ignore
24
- open.default.mockImplementation(() => {
25
- throw new TypeError('x is not a function')
26
- })
27
- // TODO should say that is is a TypeError
28
- await expect(Native.openFolder('/test')).rejects.toThrowError(
29
- new Error('Failed to open /test: x is not a function')
30
- )
31
- })
@@ -1,68 +0,0 @@
1
- import { createWriteStream } from 'node:fs'
2
- import * as fs from 'node:fs/promises'
3
- import { mkdtemp } from 'node:fs/promises'
4
- import { tmpdir } from 'node:os'
5
- import { join } from 'node:path'
6
- import { jest } from '@jest/globals'
7
- import waitForExpect from 'wait-for-expect'
8
- import * as OutputChannel from '../src/parts/OutputChannel/OutputChannel.js'
9
- import * as Platform from '../src/parts/Platform/Platform.js'
10
-
11
- const getTmpDir = () => {
12
- return mkdtemp(join(tmpdir(), 'foo-'))
13
- }
14
-
15
- if (Platform.isWindows()) {
16
- test.todo('output channel test')
17
- } else {
18
- test('writing to channel via stream', async () => {
19
- const tmpDir = await getTmpDir()
20
- await fs.writeFile(join(tmpDir, 'log.txt'), '')
21
- const onData = jest.fn()
22
- const state = OutputChannel.open(join(tmpDir, 'log.txt'), onData)
23
- const writeStream = createWriteStream(join(tmpDir, 'log.txt'))
24
- writeStream.write('a')
25
- await waitForExpect(() => {
26
- expect(onData).toHaveBeenNthCalledWith(1, 'a')
27
- })
28
- writeStream.write('b')
29
- await waitForExpect(() => {
30
- expect(onData).toHaveBeenNthCalledWith(2, 'b')
31
- })
32
- writeStream.write('c')
33
- writeStream.close()
34
- await waitForExpect(() => {
35
- expect(onData).toHaveBeenNthCalledWith(3, 'c')
36
- })
37
- OutputChannel.dispose(state)
38
- })
39
-
40
- test('writing to channel', async () => {
41
- const tmpDir = await getTmpDir()
42
- await fs.writeFile(join(tmpDir, 'log.txt'), '')
43
- const onData = jest.fn()
44
- const state = OutputChannel.open(join(tmpDir, 'log.txt'), onData)
45
- await fs.writeFile(join(tmpDir, 'log.txt'), 'abc\n')
46
- await waitForExpect(() => {
47
- expect(onData).toHaveBeenCalledWith('abc\n')
48
- })
49
- OutputChannel.dispose(state)
50
- })
51
-
52
- test('non-existing file', async () => {
53
- const tmpDir = await getTmpDir()
54
- const onData = jest.fn()
55
- const onError = jest.fn()
56
- const state = OutputChannel.open(
57
- join(tmpDir, 'non-existing-file.txt'),
58
- onData,
59
- onError
60
- )
61
- expect(onError).toHaveBeenCalledWith(
62
- expect.stringMatching(
63
- /^Error: ENOENT: no such file or directory, access /
64
- )
65
- )
66
- OutputChannel.dispose(state)
67
- })
68
- }
package/test/Path.test.js DELETED
@@ -1,17 +0,0 @@
1
- import * as Path from '../src/parts/Path/Path.js'
2
-
3
- test('join', () => {
4
- if (process.platform === 'win32') {
5
- expect(Path.join('test', 'my-file.txt')).toBe('test\\my-file.txt')
6
- } else {
7
- expect(Path.join('test', 'my-file.txt')).toBe('test/my-file.txt')
8
- }
9
- })
10
-
11
- test('dirname', () => {
12
- if (process.platform === 'win32') {
13
- expect(Path.dirname('test\\my-file.txt')).toBe('test')
14
- } else {
15
- expect(Path.dirname('test/my-file.txt')).toBe('test')
16
- }
17
- })
@@ -1,61 +0,0 @@
1
- import * as Platform from '../src/parts/Platform/Platform.js'
2
-
3
- test('isWindows', () => {
4
- expect(Platform.isWindows()).toEqual(expect.any(Boolean))
5
- })
6
-
7
- test('isMacOs', () => {
8
- expect(Platform.isMacOs()).toEqual(expect.any(Boolean))
9
- })
10
-
11
- test('getDataDir', () => {
12
- expect(Platform.getDataDir()).toEqual(expect.any(String))
13
- })
14
-
15
- test('getConfigDir', () => {
16
- expect(Platform.getConfigDir()).toEqual(expect.any(String))
17
- })
18
-
19
- test('getCacheDir', () => {
20
- expect(Platform.getCacheDir()).toEqual(expect.any(String))
21
- })
22
-
23
- test('getHomeDir', () => {
24
- expect(Platform.getHomeDir()).toEqual(expect.any(String))
25
- })
26
-
27
- test('getCachedExtensionsPath', () => {
28
- expect(Platform.getCachedExtensionsPath()).toEqual(expect.any(String))
29
- })
30
-
31
- test('getBuiltinExtensionsPath', () => {
32
- expect(Platform.getBuiltinExtensionsPath()).toEqual(expect.any(String))
33
- })
34
-
35
- test('getDisabledExtensionsPath', () => {
36
- expect(Platform.getDisabledExtensionsPath()).toEqual(expect.any(String))
37
- })
38
-
39
- test('getMarketplaceUrl', () => {
40
- expect(Platform.getMarketplaceUrl()).toEqual(expect.any(String))
41
- })
42
-
43
- test('getDesktop', () => {
44
- expect(Platform.getDesktop()).toEqual(expect.any(String))
45
- })
46
-
47
- test('getPathSeparator', () => {
48
- expect(Platform.getPathSeparator()).toEqual(expect.any(String))
49
- })
50
-
51
- test('getLogsDir', () => {
52
- expect(Platform.getLogsDir()).toEqual(expect.any(String))
53
- })
54
-
55
- test('getUserSettingsPath', () => {
56
- expect(Platform.getUserSettingsPath()).toEqual(expect.any(String))
57
- })
58
-
59
- test('getRecentlyOpenedPath', () => {
60
- expect(Platform.getRecentlyOpenedPath()).toEqual(expect.any(String))
61
- })
@@ -1,140 +0,0 @@
1
- import { mkdtemp, readFile, writeFile, mkdir } from 'node:fs/promises'
2
- import { tmpdir } from 'node:os'
3
- import { join } from 'node:path'
4
- import * as Platform from '../src/parts/Platform/Platform.js'
5
- import * as Preferences from '../src/parts/Preferences/Preferences.js'
6
-
7
- const getTmpDir = () => {
8
- return mkdtemp(join(tmpdir(), 'foo-'))
9
- }
10
-
11
- // test.skip('getAll - no preferences exist', async () => {
12
- // const tmpDir = await getTmpDir()
13
- // Platform.state.getConfigDir = () => {
14
- // return tmpDir
15
- // }
16
- // expect(await Preferences.getAll()).toEqual({
17
- // 'editor.fontFamily': "'Fira Code'",
18
- // 'editor.fontSize': 14,
19
- // 'extensions.autoUpdate': true,
20
- // 'workbench.activityBar.visible': true,
21
- // 'workbench.colorTheme': 'slime',
22
- // 'workbench.iconTheme': 'vscode-icons',
23
- // 'workbench.sideBar.visible': true,
24
- // })
25
- // })
26
-
27
- // test('set - no preferences exist', async () => {
28
- // const tmpDir = await getTmpDir()
29
- // Platform.state.getConfigDir = () => {
30
- // return tmpDir
31
- // }
32
- // await Preferences.set('sample-key', 'sample-value')
33
- // expect(await readFile(join(tmpDir, 'settings.json'), 'utf-8')).toBe(`{
34
- // \"sample-key\": \"sample-value\"
35
- // }
36
- // `)
37
- // })
38
-
39
- // test('set - no preferences exist in nested folder', async () => {
40
- // const tmpDir = await getTmpDir()
41
- // Platform.state.getConfigDir = () => {
42
- // return join(tmpDir, 'my-app', 'nested')
43
- // }
44
- // await Preferences.set('sample-key', 'sample-value')
45
- // expect(
46
- // await readFile(join(tmpDir, 'my-app', 'nested', 'settings.json'), 'utf-8')
47
- // ).toBe(`{
48
- // \"sample-key\": \"sample-value\"
49
- // }
50
- // `)
51
- // })
52
-
53
- // test('set - preferences exist', async () => {
54
- // const tmpDir = await getTmpDir()
55
- // Platform.state.getConfigDir = () => {
56
- // return tmpDir
57
- // }
58
- // await writeFile(
59
- // join(tmpDir, 'settings.json'),
60
- // JSON.stringify({
61
- // 'key-0': '0',
62
- // }) + '\n'
63
- // )
64
- // await Preferences.set('sample-key', 'sample-value')
65
- // expect(await readFile(join(tmpDir, 'settings.json'), 'utf-8')).toBe(`{
66
- // \"key-0\": \"0\",
67
- // \"sample-key\": \"sample-value\"
68
- // }
69
- // `)
70
- // })
71
-
72
- // test.skip('set - preferences exist but are invalid json', async () => {
73
- // const tmpDir = await getTmpDir()
74
- // Platform.state.getConfigDir = () => {
75
- // return tmpDir
76
- // }
77
- // const settingsPath = join(tmpDir, 'settings.json')
78
- // await writeFile(settingsPath, `"`)
79
- // // TODO should handle error gracefully
80
- // await expect(
81
- // Preferences.set('sample-key', 'sample-value')
82
- // ).rejects.toThrowError(
83
- // new Error(
84
- // `Unexpected end of JSON input while parsing "\\"" in ${settingsPath}`
85
- // )
86
- // )
87
- // })
88
-
89
- test('getAll - error', async () => {
90
- const tmpDir = await getTmpDir()
91
- Platform.state.getAppDir = () => {
92
- return tmpDir
93
- }
94
- await expect(Preferences.getAll()).rejects.toThrowError(
95
- /^Failed to get all preferences: Failed to load default preferences: ENOENT/
96
- )
97
- })
98
-
99
- // test('getDefaultPreferences - error', async () => {
100
- // const tmpDir = await getTmpDir()
101
- // Platform.state.getAppDir = () => {
102
- // return tmpDir
103
- // }
104
- // await expect(Preferences.getDefaultPreferences()).rejects.toThrowError(
105
- // /^Failed to load default preferences: ENOENT/
106
- // )
107
- // })
108
-
109
- // test('set - error', async () => {
110
- // const tmpDir = await getTmpDir()
111
- // await mkdir(join(tmpDir, 'settings.json'))
112
- // Platform.state.getConfigDir = () => {
113
- // return tmpDir
114
- // }
115
- // await expect(Preferences.set('x', 42)).rejects.toThrowError(
116
- // /^Failed to set key in user settings: failed to get user preferences: EISDIR/
117
- // )
118
- // })
119
-
120
- // test('getUserSettingsContent - error', async () => {
121
- // const tmpDir = await getTmpDir()
122
- // await mkdir(join(tmpDir, 'settings.json'))
123
- // Platform.state.getConfigDir = () => {
124
- // return tmpDir
125
- // }
126
- // await expect(Preferences.getUserSettingsContent()).rejects.toThrowError(
127
- // /^Failed to load user settings: EISDIR/
128
- // )
129
- // })
130
-
131
- // test('setUserSettingsContent - error', async () => {
132
- // const tmpDir = await getTmpDir()
133
- // await mkdir(join(tmpDir, 'settings.json'))
134
- // Platform.state.getConfigDir = () => {
135
- // return tmpDir
136
- // }
137
- // await expect(Preferences.setUserSettingsContent('')).rejects.toThrowError(
138
- // /^Failed to write to user settings file: EISDIR/
139
- // )
140
- // })
@@ -1,9 +0,0 @@
1
- import * as Process from '../src/parts/Process/Process.js'
2
-
3
- test('crash', () => {
4
- expect(Process.crash).toThrow()
5
- })
6
-
7
- test('crashAsync', () => {
8
- expect(Process.crashAsync).rejects.toThrow()
9
- })
@@ -1,5 +0,0 @@
1
- import * as RgPath from '../src/parts/RgPath/RgPath.js'
2
-
3
- test('rgPath', () => {
4
- expect(RgPath.rgPath).toEqual(expect.any(String))
5
- })
@@ -1,45 +0,0 @@
1
- import { mkdtemp } from 'node:fs/promises'
2
- import { tmpdir } from 'node:os'
3
- import { join, sep } from 'node:path'
4
- import { writeFile } from '../src/parts/FileSystem/FileSystem.js'
5
- import * as Search from '../src/parts/Search/Search.js'
6
-
7
- const getTmpDir = () => {
8
- return mkdtemp(join(tmpdir(), 'foo-'))
9
- }
10
-
11
- const fixPath = (path) => {
12
- return path.replaceAll('/', sep)
13
- }
14
-
15
- test('search', async () => {
16
- const tmpDir = await getTmpDir()
17
- await writeFile(
18
- join(tmpDir, 'index.html'),
19
- `<!DOCTYPE html>
20
- <html lang="en">
21
- <head>
22
- <meta charset="UTF-8" />
23
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
24
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
25
- <title>Document</title>
26
- </head>
27
- <body></body>
28
- </html>
29
- `
30
- )
31
- expect(await Search.search(tmpDir, 'Document')).toEqual({
32
- results: [
33
- [
34
- fixPath('./index.html'),
35
- [
36
- {
37
- absoluteOffset: 208,
38
- preview: ' <title>Document</title>\n',
39
- },
40
- ],
41
- ],
42
- ],
43
- stats: expect.any(Object),
44
- })
45
- })
@@ -1,80 +0,0 @@
1
- import { mkdtemp } from 'node:fs/promises'
2
- import { tmpdir } from 'node:os'
3
- import { dirname, join, sep } from 'node:path'
4
- import { fileURLToPath } from 'node:url'
5
- import { mkdir, writeFile } from '../src/parts/FileSystem/FileSystem.js'
6
- import { searchFile } from '../src/parts/SearchFile/SearchFile.js'
7
-
8
- const __dirname = dirname(fileURLToPath(import.meta.url))
9
-
10
- const getTmpDir = () => {
11
- return mkdtemp(join(tmpdir(), 'foo-'))
12
- }
13
-
14
- const fixPath = (path) => {
15
- return path.replaceAll('/', sep)
16
- }
17
-
18
- let tmpDir
19
-
20
- beforeAll(async () => {
21
- tmpDir = await getTmpDir()
22
- await writeFile(join(tmpDir, 'fileA'), '')
23
- await writeFile(join(tmpDir, 'fileB'), '')
24
- await mkdir(join(tmpDir, 'nested'))
25
- await writeFile(join(tmpDir, 'nested', 'fileC'), '')
26
- })
27
-
28
- test('searchFile - exact match', async () => {
29
- expect(await searchFile(tmpDir, 'fileA')).toEqual([
30
- fixPath('fileA'),
31
- fixPath('fileB'),
32
- fixPath('nested/fileC'),
33
- ])
34
- })
35
-
36
- test('searchFile - match filename in nested folder', async () => {
37
- expect(await searchFile(tmpDir, 'fileC')).toEqual([
38
- fixPath('fileA'),
39
- fixPath('fileB'),
40
- fixPath('nested/fileC'),
41
- ])
42
- })
43
-
44
- test('searchFile - match files that start with searchTerm', async () => {
45
- expect(await searchFile(tmpDir, 'file')).toEqual([
46
- fixPath('fileA'),
47
- fixPath('fileB'),
48
- fixPath('nested/fileC'),
49
- ])
50
- })
51
-
52
- test('searchFile - match files that contain searchTerm', async () => {
53
- expect(await searchFile(tmpDir, 'ile')).toEqual([
54
- fixPath('fileA'),
55
- fixPath('fileB'),
56
- fixPath('nested/fileC'),
57
- ])
58
- })
59
-
60
- test('searchFile - match files that end with searchTerm', async () => {
61
- expect(await searchFile(tmpDir, 'eA')).toEqual([
62
- fixPath('fileA'),
63
- fixPath('fileB'),
64
- fixPath('nested/fileC'),
65
- ])
66
- })
67
-
68
- test('searchFile - no matching files', async () => {
69
- expect(
70
- await searchFile(`${__dirname}/fixture-search-file-1`, 'non-existing')
71
- ).toEqual([fixPath('fileA'), fixPath('fileB'), fixPath('nested/fileC')])
72
- })
73
-
74
- test('searchFile - empty string', async () => {
75
- expect(await searchFile(`${__dirname}/fixture-search-file-1`, '')).toEqual([
76
- fixPath('fileA'),
77
- fixPath('fileB'),
78
- fixPath('nested/fileC'),
79
- ])
80
- })
@@ -1,53 +0,0 @@
1
- import { Buffer } from 'node:buffer'
2
- import waitForExpect from 'wait-for-expect'
3
- import * as Platform from '../src/parts/Platform/Platform.js'
4
- import * as Terminal from '../src/parts/Terminal/Terminal.js'
5
-
6
- afterEach(() => {
7
- Terminal.disposeAll()
8
- })
9
-
10
- test.skip('Terminal', async () => {
11
- if (Platform.isWindows()) {
12
- // TODO add windows test
13
- return
14
- }
15
- let allData = ''
16
- const socket = {
17
- send(message) {
18
- const parsed = JSON.parse(message)
19
- console.log({ parsed })
20
- const data = Buffer.from(parsed.params[2].data).toString()
21
- allData += data
22
- console.log({ allData })
23
- },
24
- on(event, listener) {},
25
- }
26
- Terminal.create(socket, 0, '/tmp')
27
- Terminal.write(0, 'abc')
28
- await waitForExpect(() => {
29
- expect(allData).toContain('abc')
30
- // expect(true).toBe(false)
31
- // expect(allData).toContain('abc')
32
- // expect(socket.send).toHaveBeenCalledWith('abc')
33
- })
34
- })
35
-
36
- // test.skip('Terminal echo', async () => {
37
- // await new Promise((resolve) => {
38
- // // @ts-ignore
39
- // const terminal = create({
40
- // env: {
41
- // TEST: '`',
42
- // },
43
- // handleData(data) {
44
- // if (data.toString().includes('`')) {
45
- // terminal.dispose()
46
- // // @ts-ignore
47
- // resolve()
48
- // }
49
- // },
50
- // })
51
- // terminal.write('echo $TEST\n')
52
- // })
53
- // })
@@ -1,34 +0,0 @@
1
- import { jest } from '@jest/globals'
2
-
3
- afterEach(() => {
4
- jest.resetAllMocks()
5
- })
6
-
7
- jest.unstable_mockModule('trash', () => {
8
- return {
9
- default: jest.fn(() => {
10
- throw new Error('not implemented')
11
- }),
12
- }
13
- })
14
-
15
- const trash = await import('trash')
16
- const Trash = await import('../src/parts/Trash/Trash.js')
17
-
18
- test('trash', async () => {
19
- // @ts-ignore
20
- trash.default.mockImplementation(() => {})
21
- await Trash.trash('/test')
22
- expect(trash.default).toHaveBeenCalledTimes(1)
23
- expect(trash.default).toHaveBeenCalledWith('/test')
24
- })
25
-
26
- test('trash - error', async () => {
27
- // @ts-ignore
28
- trash.default.mockImplementation(() => {
29
- throw new TypeError('x is not a function')
30
- })
31
- await expect(Trash.trash('/test')).rejects.toThrowError(
32
- new Error('Failed to move item to trash: x is not a function')
33
- )
34
- })
@@ -1,98 +0,0 @@
1
- import http from 'node:http'
2
- import { mkdtemp, writeFile } from 'node:fs/promises'
3
- import { tmpdir } from 'node:os'
4
- import { join } from 'node:path'
5
- import { WebSocket } from 'ws'
6
- import * as WebSocketServer from '../src/parts/WebSocketServer/WebSocketServer.js'
7
-
8
- const getTmpDir = () => {
9
- return mkdtemp(join(tmpdir(), 'foo-'))
10
- }
11
-
12
- test('WebSocketServer', async () => {
13
- const httpServer = http.createServer((req, res) => {
14
- WebSocketServer.handleUpgrade(
15
- {
16
- headers: req.headers,
17
- method: req.method,
18
- },
19
- req.socket
20
- )
21
- })
22
- const port = await new Promise((resolve, reject) => {
23
- httpServer.listen(0, () => {
24
- const address = httpServer.address()
25
- if (address === null || typeof address === 'string') {
26
- reject(new Error('unexpected address type'))
27
- return
28
- }
29
- resolve(address.port)
30
- })
31
- })
32
- const webSocket = new WebSocket(`ws://localhost:${port}`)
33
- await new Promise((resolve) => {
34
- webSocket.onopen = () => {
35
- resolve(undefined)
36
- }
37
- })
38
- const messageBufferPromise = new Promise((resolve) => {
39
- webSocket.on('message', (message) => {
40
- resolve(message)
41
- })
42
- })
43
- const tmpDir = await getTmpDir()
44
- await writeFile(join(tmpDir, 'abc.txt'), 'abc')
45
- webSocket.send(
46
- JSON.stringify({
47
- jsonrpc: '2.0',
48
- method: /* FileSystem.readFile */ 'FileSystem.readFile',
49
- params: [join(tmpDir, 'abc.txt')],
50
- id: 1,
51
- })
52
- )
53
- const messageBuffer = await messageBufferPromise
54
- const messageString = messageBuffer.toString()
55
- const message = JSON.parse(messageString)
56
- expect(message).toEqual({
57
- id: 1,
58
- jsonrpc: '2.0',
59
- result: 'abc',
60
- })
61
- webSocket.close()
62
- httpServer.close()
63
- })
64
-
65
- // TODO have e2e test for socket error handling (e.g. rangeError or connection died or EPIPE)
66
-
67
- // TODO how to emit and test error?
68
- test.skip('WebSocketServer - handle socket error', async () => {
69
- const httpServer = http.createServer((req, res) => {
70
- WebSocketServer.handleUpgrade(
71
- {
72
- headers: req.headers,
73
- method: req.method,
74
- },
75
- req.socket
76
- )
77
- req.socket._destroy(new RangeError('invalid range specified'), () => {})
78
- // setInterval(() => {
79
- // req.socket.emit('error', new RangeError('invalid range specified'))
80
- // }, 100)
81
- })
82
- const port = await new Promise((resolve, reject) => {
83
- httpServer.listen(0, () => {
84
- const address = httpServer.address()
85
- if (address === null || typeof address === 'string') {
86
- reject(new Error('unexpected address type'))
87
- return
88
- }
89
- resolve(address.port)
90
- })
91
- })
92
- const webSocket = new ws.WebSocket(`ws://localhost:${port}`)
93
- await new Promise((resolve) => {
94
- webSocket.onopen = () => {
95
- resolve()
96
- }
97
- })
98
- })
@@ -1,10 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Document</title>
8
- </head>
9
- <body></body>
10
- </html>
File without changes