@lvce-editor/shared-process 0.0.2
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/LICENSE +21 -0
- package/README.md +41 -0
- package/bin/sharedProcess.js +3 -0
- package/index.js +6 -0
- package/package.json +96 -0
- package/src/parts/Assert/Assert.js +57 -0
- package/src/parts/Callback/Callback.js +48 -0
- package/src/parts/ChildProcess/ChildProcess.js +98 -0
- package/src/parts/ClipBoard/ClipBoard.ipc.js +7 -0
- package/src/parts/ClipBoard/ClipBoard.js +23 -0
- package/src/parts/ClipBoard/ClipBoardGnome.js +78 -0
- package/src/parts/ClipBoard/ClipBoardNoop.js +14 -0
- package/src/parts/ClipBoard/ClipBoardWindows.js +22 -0
- package/src/parts/Command/Command.js +264 -0
- package/src/parts/Configuration/Configuration.ipc.js +7 -0
- package/src/parts/Configuration/Configuration.js +39 -0
- package/src/parts/Credentials/Credentials.ipc.js +10 -0
- package/src/parts/Credentials/Credentials.js +69 -0
- package/src/parts/Debug/Debug.js +3 -0
- package/src/parts/Developer/Developer.ipc.js +20 -0
- package/src/parts/Developer/Developer.js +132 -0
- package/src/parts/Download/Download.js +33 -0
- package/src/parts/Electron/Electron.ipc.js +19 -0
- package/src/parts/Electron/Electron.js +99 -0
- package/src/parts/Env/Env.js +3 -0
- package/src/parts/Error/Error.js +30 -0
- package/src/parts/ErrorHandling/ErrorHandling.js +40 -0
- package/src/parts/Exec/Exec.js +16 -0
- package/src/parts/Extension/Extension.js +7 -0
- package/src/parts/ExtensionHost/ExtensionHost.ipc.js +80 -0
- package/src/parts/ExtensionHost/ExtensionHost.js +163 -0
- package/src/parts/ExtensionHost/ExtensionHostBraceCompletion.js +14 -0
- package/src/parts/ExtensionHost/ExtensionHostClosingTag.js +14 -0
- package/src/parts/ExtensionHost/ExtensionHostColorTheme.js +60 -0
- package/src/parts/ExtensionHost/ExtensionHostCommand.js +19 -0
- package/src/parts/ExtensionHost/ExtensionHostCompletion.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostDefinition.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostDiagnostic.js +7 -0
- package/src/parts/ExtensionHost/ExtensionHostFileSystem.js +23 -0
- package/src/parts/ExtensionHost/ExtensionHostFormatting.js +4 -0
- package/src/parts/ExtensionHost/ExtensionHostHover.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostIconTheme.js +35 -0
- package/src/parts/ExtensionHost/ExtensionHostImplementation.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostKeyBindings.js +23 -0
- package/src/parts/ExtensionHost/ExtensionHostLanguages.js +84 -0
- package/src/parts/ExtensionHost/ExtensionHostManagement.js +26 -0
- package/src/parts/ExtensionHost/ExtensionHostOutput.js +3 -0
- package/src/parts/ExtensionHost/ExtensionHostQuickPick.js +6 -0
- package/src/parts/ExtensionHost/ExtensionHostReference.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostRename.js +27 -0
- package/src/parts/ExtensionHost/ExtensionHostSemanticTokens.js +10 -0
- package/src/parts/ExtensionHost/ExtensionHostSourceControl.js +15 -0
- package/src/parts/ExtensionHost/ExtensionHostStats.js +3 -0
- package/src/parts/ExtensionHost/ExtensionHostStatusBar.js +7 -0
- package/src/parts/ExtensionHost/ExtensionHostTabCompletion.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostTextDocument.js +35 -0
- package/src/parts/ExtensionHost/ExtensionHostTypeDefinition.js +12 -0
- package/src/parts/ExtensionHost/ExtensionHostWorkspace.js +3 -0
- package/src/parts/ExtensionManagement/ExtensionManagement.ipc.js +11 -0
- package/src/parts/ExtensionManagement/ExtensionManagement.js +319 -0
- package/src/parts/FileSystem/FileSystem.ipc.js +32 -0
- package/src/parts/FileSystem/FileSystem.js +228 -0
- package/src/parts/Git/Git.js +58 -0
- package/src/parts/Json/Json.js +67 -0
- package/src/parts/JsonFile/JsonFile.js +14 -0
- package/src/parts/JsonRpc/JsonRpc.js +22 -0
- package/src/parts/Native/Native.ipc.js +6 -0
- package/src/parts/Native/Native.js +14 -0
- package/src/parts/OutputChannel/OutputChannel.ipc.js +51 -0
- package/src/parts/OutputChannel/OutputChannel.js +37 -0
- package/src/parts/ParentIpc/ParentIpc.js +203 -0
- package/src/parts/Path/Path.js +17 -0
- package/src/parts/Platform/Platform.ipc.js +18 -0
- package/src/parts/Platform/Platform.js +165 -0
- package/src/parts/Preferences/Preferences.ipc.js +6 -0
- package/src/parts/Preferences/Preferences.js +75 -0
- package/src/parts/PrettyError/PrettyError.js +86 -0
- package/src/parts/Process/Process.ipc.js +7 -0
- package/src/parts/Process/Process.js +7 -0
- package/src/parts/Queue/Queue.js +35 -0
- package/src/parts/RequiresSocket/RequiresSocket.js +11 -0
- package/src/parts/RgPath/RgPath.js +1 -0
- package/src/parts/Root/Root.js +6 -0
- package/src/parts/Search/Search.ipc.js +6 -0
- package/src/parts/Search/Search.js +101 -0
- package/src/parts/SearchFile/SearchFile.ipc.js +6 -0
- package/src/parts/SearchFile/SearchFile.js +51 -0
- package/src/parts/Socket/Socket.js +132 -0
- package/src/parts/Stats/Stats.js +45 -0
- package/src/parts/Terminal/Terminal.ipc.js +45 -0
- package/src/parts/Terminal/Terminal.js +161 -0
- package/src/parts/TextDocument/TextDocument.ipc.js +6 -0
- package/src/parts/TextDocument/TextDocument.js +37 -0
- package/src/parts/Trace/Trace.js +15 -0
- package/src/parts/Trash/Trash.js +11 -0
- package/src/parts/WebSocketServer/WebSocketServer.ipc.js +6 -0
- package/src/parts/WebSocketServer/WebSocketServer.js +43 -0
- package/src/parts/Workspace/Workspace.ipc.js +7 -0
- package/src/parts/Workspace/Workspace.js +107 -0
- package/src/sharedProcessMain.js +61 -0
- package/test/Callback.test.js +42 -0
- package/test/ClipBoard.test.js +105 -0
- package/test/Credentials.test.js +147 -0
- package/test/Developer.test.js +34 -0
- package/test/Electron.test.js +93 -0
- package/test/Error.test.js +16 -0
- package/test/Exec.test.js +25 -0
- package/test/ExtensionHost.test.js +127 -0
- package/test/ExtensionHostColorTheme.test.js +141 -0
- package/test/ExtensionHostCommand.test.js +27 -0
- package/test/ExtensionHostCompletion.test.js +45 -0
- package/test/ExtensionHostDefinition.test.js +35 -0
- package/test/ExtensionHostDiagnostic.test.js +23 -0
- package/test/ExtensionHostFileSystem.test.js +91 -0
- package/test/ExtensionHostFormatting.test.js +27 -0
- package/test/ExtensionHostIconTheme.test.js +73 -0
- package/test/ExtensionHostLanguages.test.js +212 -0
- package/test/ExtensionHostOutput.test.js +23 -0
- package/test/ExtensionHostRename.test.js +59 -0
- package/test/ExtensionHostSemanticTokens.test.js +26 -0
- package/test/ExtensionHostTabCompletion.test.js +35 -0
- package/test/ExtensionHostTextDocument.test.js +61 -0
- package/test/ExtensionHostTypeDefinition.test.js +35 -0
- package/test/ExtensionHostWorkspace.test.js +21 -0
- package/test/ExtensionManagement.test.js +408 -0
- package/test/FileSystem.test.js +294 -0
- package/test/Json.test.js +25 -0
- package/test/Native.test.js +31 -0
- package/test/OutputChannel.test.js +68 -0
- package/test/Path.test.js +17 -0
- package/test/Platform.test.js +61 -0
- package/test/Preferences.test.js +140 -0
- package/test/Process.test.js +9 -0
- package/test/RgPath.test.js +5 -0
- package/test/Search.test.js +45 -0
- package/test/SearchFile.test.js +80 -0
- package/test/Terminal.test.js +53 -0
- package/test/Trash.test.js +34 -0
- package/test/WebSocketServer.test.js +98 -0
- package/test/fixture-search-1/index.html +10 -0
- package/test/fixture-search-file-1/fileA +0 -0
- package/test/fixture-search-file-1/fileB +0 -0
- package/test/fixture-search-file-1/nested/fileC +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { dirname, join } from 'node:path'
|
|
4
|
+
import * as ExtensionHostColorTheme from '../src/parts/ExtensionHost/ExtensionHostColorTheme.js'
|
|
5
|
+
import * as Platform from '../src/parts/Platform/Platform.js'
|
|
6
|
+
import * as ExtensionManagement from '../src/parts/ExtensionManagement/ExtensionManagement.js'
|
|
7
|
+
import * as JsonFile from '../src/parts/JsonFile/JsonFile.js'
|
|
8
|
+
|
|
9
|
+
const getTmpDir = () => {
|
|
10
|
+
return mkdtemp(join(tmpdir(), 'foo-'))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
test('getColorThemeNames - empty', async () => {
|
|
14
|
+
const tmpDir = await getTmpDir()
|
|
15
|
+
Platform.state.getExtensionsPath = () => {
|
|
16
|
+
return tmpDir
|
|
17
|
+
}
|
|
18
|
+
Platform.state.getBuiltinExtensionsPath = () => {
|
|
19
|
+
return tmpDir
|
|
20
|
+
}
|
|
21
|
+
expect(await ExtensionHostColorTheme.getColorThemes()).toEqual([])
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test.skip('getColorThemeJson - theme id contains number', async () => {
|
|
25
|
+
const tmpDir = await getTmpDir()
|
|
26
|
+
ExtensionManagement.state.getThemeExtensions = async () => {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
status: 'fulfilled',
|
|
30
|
+
id: 'builtin.test-cobalt2',
|
|
31
|
+
colorThemes: [
|
|
32
|
+
{
|
|
33
|
+
id: 'cobalt2',
|
|
34
|
+
label: 'Cobalt2 Theme',
|
|
35
|
+
path: 'color-theme.json',
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
path: join(tmpDir, 'builtin.theme-cobalt-2'),
|
|
39
|
+
},
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
const colorThemePath = join(
|
|
43
|
+
tmpDir,
|
|
44
|
+
'builtin.theme-cobalt2',
|
|
45
|
+
'color-theme.json'
|
|
46
|
+
)
|
|
47
|
+
await mkdir(dirname(colorThemePath), { recursive: true })
|
|
48
|
+
await writeFile(colorThemePath, '{}')
|
|
49
|
+
expect(await ExtensionHostColorTheme.getColorThemeJson('cobalt2')).toEqual({})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('getColorThemeJson - invalid json', async () => {
|
|
53
|
+
const tmpDir = await getTmpDir()
|
|
54
|
+
Platform.state.getBuiltinExtensionsPath = () => {
|
|
55
|
+
return tmpDir
|
|
56
|
+
}
|
|
57
|
+
await JsonFile.writeJson(
|
|
58
|
+
join(tmpDir, 'builtin.theme-test', 'extension.json'),
|
|
59
|
+
{
|
|
60
|
+
id: 'builtin.test-theme',
|
|
61
|
+
colorThemes: [
|
|
62
|
+
{
|
|
63
|
+
id: 'test-theme',
|
|
64
|
+
label: 'Test Theme',
|
|
65
|
+
path: 'color-theme.json',
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
path: tmpDir,
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
const colorThemePath = join(tmpDir, 'builtin.theme-test', 'color-theme.json')
|
|
72
|
+
await writeFile(colorThemePath, '{ 1 }')
|
|
73
|
+
await expect(
|
|
74
|
+
ExtensionHostColorTheme.getColorThemeJson('test-theme')
|
|
75
|
+
).rejects.toThrowError(
|
|
76
|
+
'Failed to load color theme "test-theme": Unexpected number in JSON at position 2 while parsing \'{ 1 }\''
|
|
77
|
+
)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test('getColorThemeJson - wrong/invalid path', async () => {
|
|
81
|
+
const tmpDir = await getTmpDir()
|
|
82
|
+
Platform.state.getBuiltinExtensionsPath = () => {
|
|
83
|
+
return tmpDir
|
|
84
|
+
}
|
|
85
|
+
await JsonFile.writeJson(
|
|
86
|
+
join(tmpDir, 'builtin.theme-test', 'extension.json'),
|
|
87
|
+
{
|
|
88
|
+
id: 'builtin.theme-test',
|
|
89
|
+
colorThemes: [
|
|
90
|
+
{
|
|
91
|
+
id: 'test-theme',
|
|
92
|
+
label: 'Test Theme',
|
|
93
|
+
path: 'color-theme.json',
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
path: tmpDir,
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
const colorThemePath = join(tmpDir, 'builtin.theme-test', 'color-theme.json')
|
|
100
|
+
await expect(
|
|
101
|
+
ExtensionHostColorTheme.getColorThemeJson('test-theme')
|
|
102
|
+
).rejects.toThrowError(
|
|
103
|
+
`Failed to load color theme "test-theme": ENOENT: no such file or directory, open '${colorThemePath}'`
|
|
104
|
+
)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('getColorThemes', async () => {
|
|
108
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
109
|
+
return [
|
|
110
|
+
{
|
|
111
|
+
status: 'fulfilled',
|
|
112
|
+
id: 'builtin.theme-slime',
|
|
113
|
+
colorThemes: [
|
|
114
|
+
{
|
|
115
|
+
id: 'slime',
|
|
116
|
+
label: 'Slime',
|
|
117
|
+
path: 'color-theme.json',
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
path: '/test',
|
|
121
|
+
},
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
expect(await ExtensionHostColorTheme.getColorThemes()).toEqual([
|
|
125
|
+
{
|
|
126
|
+
id: 'slime',
|
|
127
|
+
label: 'Slime',
|
|
128
|
+
path: 'color-theme.json',
|
|
129
|
+
},
|
|
130
|
+
])
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
test.skip('getColorThemeJson - not found', async () => {
|
|
134
|
+
ExtensionHost.state.builtinExtensions = []
|
|
135
|
+
ExtensionHost.state.installedExtensions = []
|
|
136
|
+
await expect(
|
|
137
|
+
ExtensionHost.getColorThemeJson('test-theme')
|
|
138
|
+
).rejects.toThrowError(
|
|
139
|
+
'Color theme "test-theme" not found in extensions folder'
|
|
140
|
+
)
|
|
141
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as ExtensionHostCommand from '../src/parts/ExtensionHost/ExtensionHostCommand.js'
|
|
2
|
+
|
|
3
|
+
test('executeCommand', async () => {
|
|
4
|
+
const fakeExtensionHost = {
|
|
5
|
+
invoke(method, ...params) {
|
|
6
|
+
return {
|
|
7
|
+
params,
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
}
|
|
11
|
+
expect(
|
|
12
|
+
await ExtensionHostCommand.executeCommand(fakeExtensionHost, 1, 2, 3)
|
|
13
|
+
).toEqual({
|
|
14
|
+
params: [1, 2, 3],
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('executeCommand - error', async () => {
|
|
19
|
+
const fakeExtensionHost = {
|
|
20
|
+
invoke() {
|
|
21
|
+
throw new TypeError('x is not a function')
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
await expect(
|
|
25
|
+
ExtensionHostCommand.executeCommand(fakeExtensionHost)
|
|
26
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
27
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as ExtensionHostCompletion from '../src/parts/ExtensionHost/ExtensionHostCompletion.js'
|
|
2
|
+
|
|
3
|
+
test('executeCompletionProvider', async () => {
|
|
4
|
+
const fakeExtensionHost = {
|
|
5
|
+
invoke() {
|
|
6
|
+
return [
|
|
7
|
+
{
|
|
8
|
+
label: 'Option A',
|
|
9
|
+
snippet: 'Option A',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
label: 'Option B',
|
|
13
|
+
snippet: 'Option B',
|
|
14
|
+
},
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
expect(
|
|
19
|
+
await ExtensionHostCompletion.executeCompletionProvider(
|
|
20
|
+
fakeExtensionHost,
|
|
21
|
+
0,
|
|
22
|
+
0
|
|
23
|
+
)
|
|
24
|
+
).toEqual([
|
|
25
|
+
{
|
|
26
|
+
label: 'Option A',
|
|
27
|
+
snippet: 'Option A',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
label: 'Option B',
|
|
31
|
+
snippet: 'Option B',
|
|
32
|
+
},
|
|
33
|
+
])
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('executeCompletionProvider - error', async () => {
|
|
37
|
+
const fakeExtensionHost = {
|
|
38
|
+
invoke() {
|
|
39
|
+
throw new TypeError('x is not a function')
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
await expect(
|
|
43
|
+
ExtensionHostCompletion.executeCompletionProvider(fakeExtensionHost)
|
|
44
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
45
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as ExtensionHostDefinition from '../src/parts/ExtensionHost/ExtensionHostDefinition.js'
|
|
2
|
+
|
|
3
|
+
test('executeDefinitionProvider', async () => {
|
|
4
|
+
const fakeExtensionHost = {
|
|
5
|
+
invoke() {
|
|
6
|
+
return {
|
|
7
|
+
uri: '/test/file.txt',
|
|
8
|
+
startOffset: 0,
|
|
9
|
+
endOffset: 0,
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
expect(
|
|
14
|
+
await ExtensionHostDefinition.executeDefinitionProvider(
|
|
15
|
+
fakeExtensionHost,
|
|
16
|
+
0,
|
|
17
|
+
0
|
|
18
|
+
)
|
|
19
|
+
).toEqual({
|
|
20
|
+
uri: '/test/file.txt',
|
|
21
|
+
startOffset: 0,
|
|
22
|
+
endOffset: 0,
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('executeDefinitionProvider - error', async () => {
|
|
27
|
+
const fakeExtensionHost = {
|
|
28
|
+
invoke() {
|
|
29
|
+
throw new TypeError('x is not a function')
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
await expect(
|
|
33
|
+
ExtensionHostDefinition.executeDefinitionProvider(fakeExtensionHost)
|
|
34
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
35
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as ExtensionHostDiagnostic from '../src/parts/ExtensionHost/ExtensionHostDiagnostic.js'
|
|
2
|
+
|
|
3
|
+
test('executeDiagnosticProvider - empty', async () => {
|
|
4
|
+
const fakeExtensionHost = {
|
|
5
|
+
invoke() {
|
|
6
|
+
return []
|
|
7
|
+
},
|
|
8
|
+
}
|
|
9
|
+
expect(
|
|
10
|
+
await ExtensionHostDiagnostic.executeDiagnosticProvider(fakeExtensionHost)
|
|
11
|
+
).toEqual([])
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test('executeDiagnosticProvider - error', async () => {
|
|
15
|
+
const fakeExtensionHost = {
|
|
16
|
+
invoke() {
|
|
17
|
+
throw new TypeError('x is not a function')
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
await expect(
|
|
21
|
+
ExtensionHostDiagnostic.executeDiagnosticProvider(fakeExtensionHost, 0)
|
|
22
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
23
|
+
})
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as ExtensionHostFileSystem from '../src/parts/ExtensionHost/ExtensionHostFileSystem.js'
|
|
2
|
+
|
|
3
|
+
test('readFile', async () => {
|
|
4
|
+
const fakeExtensionHost = {
|
|
5
|
+
async invoke() {
|
|
6
|
+
return ''
|
|
7
|
+
},
|
|
8
|
+
}
|
|
9
|
+
expect(
|
|
10
|
+
await ExtensionHostFileSystem.readFile(
|
|
11
|
+
fakeExtensionHost,
|
|
12
|
+
'/test',
|
|
13
|
+
'/test/file.txt'
|
|
14
|
+
)
|
|
15
|
+
).toBe('')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('readFile - error', async () => {
|
|
19
|
+
const fakeExtensionHost = {
|
|
20
|
+
async invoke() {
|
|
21
|
+
throw new TypeError('x is not a function')
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
await expect(
|
|
25
|
+
ExtensionHostFileSystem.readFile(
|
|
26
|
+
fakeExtensionHost,
|
|
27
|
+
'test',
|
|
28
|
+
'/test/file.txt'
|
|
29
|
+
)
|
|
30
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test('writeFile', async () => {
|
|
34
|
+
const fakeExtensionHost = {
|
|
35
|
+
async invoke() {},
|
|
36
|
+
}
|
|
37
|
+
expect(
|
|
38
|
+
await ExtensionHostFileSystem.writeFile(
|
|
39
|
+
fakeExtensionHost,
|
|
40
|
+
'/test',
|
|
41
|
+
'/test/file.txt',
|
|
42
|
+
''
|
|
43
|
+
)
|
|
44
|
+
).toBeUndefined()
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
test('writeFile - error', async () => {
|
|
48
|
+
const fakeExtensionHost = {
|
|
49
|
+
async invoke() {
|
|
50
|
+
throw new TypeError('x is not a function')
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
await expect(
|
|
54
|
+
ExtensionHostFileSystem.writeFile(
|
|
55
|
+
fakeExtensionHost,
|
|
56
|
+
'test',
|
|
57
|
+
'/test/file.txt',
|
|
58
|
+
''
|
|
59
|
+
)
|
|
60
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('readDirWithFileTypes', async () => {
|
|
64
|
+
const fakeExtensionHost = {
|
|
65
|
+
async invoke() {
|
|
66
|
+
return []
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
expect(
|
|
70
|
+
await ExtensionHostFileSystem.readDirWithFileTypes(
|
|
71
|
+
fakeExtensionHost,
|
|
72
|
+
'test',
|
|
73
|
+
'/test'
|
|
74
|
+
)
|
|
75
|
+
).toEqual([])
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('readDirWithFileTypes - error', async () => {
|
|
79
|
+
const fakeExtensionHost = {
|
|
80
|
+
async invoke() {
|
|
81
|
+
throw new TypeError('x is not a function')
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
await expect(
|
|
85
|
+
ExtensionHostFileSystem.readDirWithFileTypes(
|
|
86
|
+
fakeExtensionHost,
|
|
87
|
+
'test',
|
|
88
|
+
'/test'
|
|
89
|
+
)
|
|
90
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
91
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as ExtensionHostFormatting from '../src/parts/ExtensionHost/ExtensionHostFormatting.js'
|
|
2
|
+
|
|
3
|
+
test('executeFormattingProvider', async () => {
|
|
4
|
+
const fakeExtensionHost = {
|
|
5
|
+
invoke() {
|
|
6
|
+
return ''
|
|
7
|
+
},
|
|
8
|
+
}
|
|
9
|
+
expect(
|
|
10
|
+
await ExtensionHostFormatting.format(
|
|
11
|
+
fakeExtensionHost,
|
|
12
|
+
'/test/file.txt',
|
|
13
|
+
''
|
|
14
|
+
)
|
|
15
|
+
).toEqual('')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('executeFormattingProvider - error', async () => {
|
|
19
|
+
const fakeExtensionHost = {
|
|
20
|
+
invoke() {
|
|
21
|
+
throw new TypeError('x is not a function')
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
await expect(
|
|
25
|
+
ExtensionHostFormatting.format(fakeExtensionHost, '/test/file.txt', '')
|
|
26
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
27
|
+
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { mkdtemp, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
import * as ExtensionHostIconTheme from '../src/parts/ExtensionHost/ExtensionHostIconTheme.js'
|
|
5
|
+
import * as ExtensionManagement from '../src/parts/ExtensionManagement/ExtensionManagement.js'
|
|
6
|
+
|
|
7
|
+
const getTmpDir = () => {
|
|
8
|
+
return mkdtemp(join(tmpdir(), 'foo-'))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
test('getIconTheme - not found', async () => {
|
|
12
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
13
|
+
return []
|
|
14
|
+
}
|
|
15
|
+
await expect(
|
|
16
|
+
ExtensionHostIconTheme.getIconTheme('test-theme')
|
|
17
|
+
).rejects.toThrowError(
|
|
18
|
+
'Icon theme "test-theme" not found in extensions folder'
|
|
19
|
+
)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('getIconTheme - wrong/invalid path', async () => {
|
|
23
|
+
const tmpDir = await getTmpDir()
|
|
24
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
status: 'fulfilled',
|
|
28
|
+
id: 'builtin.theme-test',
|
|
29
|
+
iconThemes: [
|
|
30
|
+
{
|
|
31
|
+
id: 'test',
|
|
32
|
+
label: 'Test',
|
|
33
|
+
path: 'icon-theme.json',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
path: tmpDir,
|
|
37
|
+
},
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
const iconThemeJsonPath = join(tmpDir, 'icon-theme.json')
|
|
41
|
+
await expect(
|
|
42
|
+
ExtensionHostIconTheme.getIconTheme('test')
|
|
43
|
+
).rejects.toThrowError(
|
|
44
|
+
`Failed to load icon theme "test": ENOENT: no such file or directory, open '${iconThemeJsonPath}'`
|
|
45
|
+
)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test('getIconTheme - invalid json', async () => {
|
|
49
|
+
const tmpDir = await getTmpDir()
|
|
50
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
status: 'fulfilled',
|
|
54
|
+
id: 'builtin.icon-theme-test',
|
|
55
|
+
iconThemes: [
|
|
56
|
+
{
|
|
57
|
+
id: 'test',
|
|
58
|
+
label: 'Test',
|
|
59
|
+
path: 'icon-theme.json',
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
path: tmpDir,
|
|
63
|
+
},
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
const iconThemeJsonPath = join(tmpDir, 'icon-theme.json')
|
|
67
|
+
await writeFile(iconThemeJsonPath, '{ 2 }')
|
|
68
|
+
await expect(
|
|
69
|
+
ExtensionHostIconTheme.getIconTheme('test')
|
|
70
|
+
).rejects.toThrowError(
|
|
71
|
+
'Failed to load icon theme "test": Unexpected number in JSON at position 2 while parsing \'{ 2 }\''
|
|
72
|
+
)
|
|
73
|
+
})
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { mkdtemp, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
import { pathToFileURL } from 'node:url'
|
|
5
|
+
import * as ExtensionHostLanguages from '../src/parts/ExtensionHost/ExtensionHostLanguages.js'
|
|
6
|
+
import * as ExtensionManagement from '../src/parts/ExtensionManagement/ExtensionManagement.js'
|
|
7
|
+
|
|
8
|
+
const getTmpDir = () => {
|
|
9
|
+
return mkdtemp(join(tmpdir(), 'foo-'))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
test('getLanguages', async () => {
|
|
13
|
+
const tmpDir = await getTmpDir()
|
|
14
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
status: 'fulfilled',
|
|
18
|
+
id: 'builtin.plaintext',
|
|
19
|
+
languages: [
|
|
20
|
+
{
|
|
21
|
+
id: 'plaintext',
|
|
22
|
+
label: 'Plaintext',
|
|
23
|
+
tokenize: 'src/tokenizePlainText.js',
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
path: tmpDir,
|
|
27
|
+
},
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
expect(await ExtensionHostLanguages.getLanguages()).toEqual([
|
|
31
|
+
{
|
|
32
|
+
id: 'plaintext',
|
|
33
|
+
label: 'Plaintext',
|
|
34
|
+
tokenize: `/remote/${pathToFileURL(
|
|
35
|
+
join(tmpDir, 'src/tokenizePlainText.js')
|
|
36
|
+
)
|
|
37
|
+
.toString()
|
|
38
|
+
.slice(8)}`,
|
|
39
|
+
},
|
|
40
|
+
])
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// TODO
|
|
44
|
+
test('getLanguages - error - property languages is not of type array', async () => {
|
|
45
|
+
const tmpDir = await getTmpDir()
|
|
46
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
47
|
+
return [
|
|
48
|
+
{
|
|
49
|
+
status: 'fulfilled',
|
|
50
|
+
id: 'builtin.plaintext',
|
|
51
|
+
languages: {},
|
|
52
|
+
path: tmpDir,
|
|
53
|
+
},
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
// TODO should handle error gracefully
|
|
57
|
+
await expect(ExtensionHostLanguages.getLanguages()).rejects.toThrowError(
|
|
58
|
+
new TypeError('extension.languages.map is not a function')
|
|
59
|
+
)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('getLanguages - language without tokenize property', async () => {
|
|
63
|
+
const tmpDir = await getTmpDir()
|
|
64
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
status: 'fulfilled',
|
|
68
|
+
id: 'builtin.icon-theme-test',
|
|
69
|
+
languages: [
|
|
70
|
+
{
|
|
71
|
+
id: 'plaintext',
|
|
72
|
+
label: 'Plaintext',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
path: tmpDir,
|
|
76
|
+
},
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
expect(await ExtensionHostLanguages.getLanguages()).toEqual([
|
|
80
|
+
{
|
|
81
|
+
id: 'plaintext',
|
|
82
|
+
label: 'Plaintext',
|
|
83
|
+
},
|
|
84
|
+
])
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('getLanguages - error - property tokenize is of type array', async () => {
|
|
88
|
+
const tmpDir = await getTmpDir()
|
|
89
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
90
|
+
return [
|
|
91
|
+
{
|
|
92
|
+
status: 'fulfilled',
|
|
93
|
+
id: 'builtin.test',
|
|
94
|
+
languages: [
|
|
95
|
+
{
|
|
96
|
+
id: 'python',
|
|
97
|
+
extensions: ['.py'],
|
|
98
|
+
configuration: './languageConfiguration.json',
|
|
99
|
+
tokenize: ['src/tokenizePython.js'],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
path: tmpDir,
|
|
103
|
+
},
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
expect(await ExtensionHostLanguages.getLanguages()).toEqual([
|
|
107
|
+
{
|
|
108
|
+
configuration: './languageConfiguration.json',
|
|
109
|
+
extensions: ['.py'],
|
|
110
|
+
id: 'python',
|
|
111
|
+
tokenize: '',
|
|
112
|
+
},
|
|
113
|
+
])
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test('getLanguageConfiguration', async () => {
|
|
117
|
+
const tmpDir = await getTmpDir()
|
|
118
|
+
await writeFile(
|
|
119
|
+
join(tmpDir, 'languageConfiguration.json'),
|
|
120
|
+
`{
|
|
121
|
+
"comments": {
|
|
122
|
+
"lineComment": "//",
|
|
123
|
+
"blockComment": ["/*", "*/"]
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
`
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
130
|
+
return [
|
|
131
|
+
{
|
|
132
|
+
status: 'fulfilled',
|
|
133
|
+
id: 'builtin.javascript',
|
|
134
|
+
languages: [
|
|
135
|
+
{
|
|
136
|
+
id: 'javascript',
|
|
137
|
+
extensions: ['.js'],
|
|
138
|
+
tokenize: 'src/tokenizeJavaScript.js',
|
|
139
|
+
configuration: './languageConfiguration.json',
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
path: tmpDir,
|
|
143
|
+
},
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
expect(
|
|
147
|
+
await ExtensionHostLanguages.getLanguageConfiguration('javascript')
|
|
148
|
+
).toEqual({
|
|
149
|
+
comments: {
|
|
150
|
+
blockComment: ['/*', '*/'],
|
|
151
|
+
lineComment: '//',
|
|
152
|
+
},
|
|
153
|
+
})
|
|
154
|
+
})
|
|
155
|
+
test('getLanguageConfiguration - error - language configuration not found', async () => {
|
|
156
|
+
const tmpDir = await getTmpDir()
|
|
157
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
158
|
+
return [
|
|
159
|
+
{
|
|
160
|
+
status: 'fulfilled',
|
|
161
|
+
id: 'builtin.javascript',
|
|
162
|
+
languages: [
|
|
163
|
+
{
|
|
164
|
+
id: 'javascript',
|
|
165
|
+
extensions: ['.js'],
|
|
166
|
+
tokenize: 'src/tokenizeJavaScript.js',
|
|
167
|
+
configuration: './languageConfiguration.json',
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
path: tmpDir,
|
|
171
|
+
},
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
const languageConfigurationPath = join(tmpDir, 'languageConfiguration.json')
|
|
175
|
+
await expect(
|
|
176
|
+
ExtensionHostLanguages.getLanguageConfiguration('javascript')
|
|
177
|
+
).rejects.toThrowError(
|
|
178
|
+
new Error(
|
|
179
|
+
`Failed to load language configuration for javascript: ENOENT: no such file or directory, open '${languageConfigurationPath}'`
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
test('getLanguageConfiguration - error - language configuration has invalid json', async () => {
|
|
185
|
+
const tmpDir = await getTmpDir()
|
|
186
|
+
await writeFile(join(tmpDir, 'languageConfiguration.json'), '{')
|
|
187
|
+
ExtensionManagement.state.getExtensions = async () => {
|
|
188
|
+
return [
|
|
189
|
+
{
|
|
190
|
+
status: 'fulfilled',
|
|
191
|
+
id: 'builtin.javascript',
|
|
192
|
+
languages: [
|
|
193
|
+
{
|
|
194
|
+
id: 'javascript',
|
|
195
|
+
extensions: ['.js'],
|
|
196
|
+
tokenize: 'src/tokenizeJavaScript.js',
|
|
197
|
+
configuration: './languageConfiguration.json',
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
path: tmpDir,
|
|
201
|
+
},
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
// TODO should display path as well
|
|
205
|
+
await expect(
|
|
206
|
+
ExtensionHostLanguages.getLanguageConfiguration('javascript')
|
|
207
|
+
).rejects.toThrowError(
|
|
208
|
+
new Error(
|
|
209
|
+
'Failed to load language configuration for javascript: Unexpected end of JSON input while parsing "{"'
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as ExtensionHostOutput from '../src/parts/ExtensionHost/ExtensionHostOutput.js'
|
|
2
|
+
|
|
3
|
+
test('getOutputChannels - empty', async () => {
|
|
4
|
+
const fakeExtensionHost = {
|
|
5
|
+
async invoke() {
|
|
6
|
+
return []
|
|
7
|
+
},
|
|
8
|
+
}
|
|
9
|
+
expect(
|
|
10
|
+
await ExtensionHostOutput.getOutputChannels(fakeExtensionHost)
|
|
11
|
+
).toEqual([])
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test('getOutputChannels - error', async () => {
|
|
15
|
+
const fakeExtensionHost = {
|
|
16
|
+
async invoke() {
|
|
17
|
+
throw new TypeError('x is not a function')
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
await expect(
|
|
21
|
+
ExtensionHostOutput.getOutputChannels(fakeExtensionHost)
|
|
22
|
+
).rejects.toThrowError(new TypeError('x is not a function'))
|
|
23
|
+
})
|