Skip to content

Commit 02b9489

Browse files
committed
refactor: add func getNlsConfiguration & tests
This PR refactors part of vscode.ts and adds a function to get the NLS Configuration. This makes the code more readable and easier to test. And it adds multiple tests for this part of the codebase.
1 parent 4b0dd07 commit 02b9489

File tree

2 files changed

+128
-21
lines changed

2 files changed

+128
-21
lines changed

src/browser/pages/vscode.ts

+67-21
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,56 @@ const options = getOptions()
55
// TODO: Add proper types.
66
/* eslint-disable @typescript-eslint/no-explicit-any */
77

8-
let nlsConfig: any
8+
// NOTE@jsjoeio
9+
// This lives here ../../../lib/vscode/src/vs/base/common/platform.ts#L106
10+
export const nlsConfigElementId = "vscode-remote-nls-configuration"
11+
12+
type NlsConfiguration = {
13+
locale: string
14+
availableLanguages: { [key: string]: string } | {}
15+
_languagePackId?: string
16+
_translationsConfigFile?: string
17+
_cacheRoot?: string
18+
_resolvedLanguagePackCoreLocation?: string
19+
_corruptedFile?: string
20+
_languagePackSupport?: boolean
21+
loadBundle?: any
22+
}
23+
24+
/**
25+
* A helper function to get the NLS Configuration settings.
26+
*
27+
* This is used by VSCode for localizations (i.e. changing
28+
* the display language).
29+
*
30+
* Make sure to wrap this in a try/catch block when you call it.
31+
**/
32+
export function getNlsConfiguration(document: Document) {
33+
const errorMsgPrefix = "[vscode]"
34+
const nlsConfigElement = document?.getElementById(nlsConfigElementId)
35+
const nlsConfig = nlsConfigElement?.getAttribute("data-settings")
36+
37+
if (!document) {
38+
throw new Error(`${errorMsgPrefix} Could not parse NLS configuration. document is undefined.`)
39+
}
40+
41+
if (!nlsConfigElement) {
42+
throw new Error(
43+
`${errorMsgPrefix} Could not parse NLS configuration. Could not find nlsConfigElement with id: ${nlsConfigElementId}`,
44+
)
45+
}
46+
47+
if (!nlsConfig) {
48+
throw new Error(
49+
`${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`,
50+
)
51+
}
52+
53+
return JSON.parse(nlsConfig) as NlsConfiguration
54+
}
55+
956
try {
10-
nlsConfig = JSON.parse(document.getElementById("vscode-remote-nls-configuration")!.getAttribute("data-settings")!)
57+
const nlsConfig = getNlsConfiguration(document)
1158
if (nlsConfig._resolvedLanguagePackCoreLocation) {
1259
const bundles = Object.create(null)
1360
nlsConfig.loadBundle = (bundle: any, _language: any, cb: any): void => {
@@ -26,26 +73,25 @@ try {
2673
.catch(cb)
2774
}
2875
}
76+
;(self.require as any) = {
77+
// Without the full URL VS Code will try to load file://.
78+
baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`,
79+
recordStats: true,
80+
paths: {
81+
"vscode-textmate": `../node_modules/vscode-textmate/release/main`,
82+
"vscode-oniguruma": `../node_modules/vscode-oniguruma/release/main`,
83+
xterm: `../node_modules/xterm/lib/xterm.js`,
84+
"xterm-addon-search": `../node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
85+
"xterm-addon-unicode11": `../node_modules/xterm-addon-unicode11/lib/xterm-addon-unicode11.js`,
86+
"xterm-addon-webgl": `../node_modules/xterm-addon-webgl/lib/xterm-addon-webgl.js`,
87+
"tas-client-umd": `../node_modules/tas-client-umd/lib/tas-client-umd.js`,
88+
"iconv-lite-umd": `../node_modules/iconv-lite-umd/lib/iconv-lite-umd.js`,
89+
jschardet: `../node_modules/jschardet/dist/jschardet.min.js`,
90+
},
91+
"vs/nls": nlsConfig,
92+
}
2993
} catch (error) {
30-
/* Probably fine. */
31-
}
32-
33-
;(self.require as any) = {
34-
// Without the full URL VS Code will try to load file://.
35-
baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`,
36-
recordStats: true,
37-
paths: {
38-
"vscode-textmate": `../node_modules/vscode-textmate/release/main`,
39-
"vscode-oniguruma": `../node_modules/vscode-oniguruma/release/main`,
40-
xterm: `../node_modules/xterm/lib/xterm.js`,
41-
"xterm-addon-search": `../node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
42-
"xterm-addon-unicode11": `../node_modules/xterm-addon-unicode11/lib/xterm-addon-unicode11.js`,
43-
"xterm-addon-webgl": `../node_modules/xterm-addon-webgl/lib/xterm-addon-webgl.js`,
44-
"tas-client-umd": `../node_modules/tas-client-umd/lib/tas-client-umd.js`,
45-
"iconv-lite-umd": `../node_modules/iconv-lite-umd/lib/iconv-lite-umd.js`,
46-
jschardet: `../node_modules/jschardet/dist/jschardet.min.js`,
47-
},
48-
"vs/nls": nlsConfig,
94+
console.error(error)
4995
}
5096

5197
try {

test/unit/browser/vscode.test.ts

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
import { JSDOM } from "jsdom"
5+
import { getNlsConfiguration, nlsConfigElementId } from "../../../src/browser/pages/vscode"
6+
7+
describe("vscode", () => {
8+
describe("getNlsConfiguration", () => {
9+
beforeEach(() => {
10+
const { window } = new JSDOM()
11+
global.document = window.document
12+
})
13+
14+
it("should throw an error if Document is undefined", () => {
15+
const errorMsgPrefix = "[vscode]"
16+
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. document is undefined.`
17+
18+
expect(() => {
19+
getNlsConfiguration(undefined as any as Document)
20+
}).toThrowError(errorMessage)
21+
})
22+
it("should throw an error if no nlsConfigElement", () => {
23+
const errorMsgPrefix = "[vscode]"
24+
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Could not find nlsConfigElement with id: ${nlsConfigElementId}`
25+
26+
expect(() => {
27+
getNlsConfiguration(document)
28+
}).toThrowError(errorMessage)
29+
})
30+
it("should throw an error if no nlsConfig", () => {
31+
const mockElement = document.createElement("div")
32+
mockElement.setAttribute("id", nlsConfigElementId)
33+
document.body.appendChild(mockElement)
34+
35+
const errorMsgPrefix = "[vscode]"
36+
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`
37+
38+
expect(() => {
39+
getNlsConfiguration(document)
40+
}).toThrowError(errorMessage)
41+
42+
document.body.removeChild(mockElement)
43+
})
44+
it("should return the correct configuration", () => {
45+
const mockElement = document.createElement("div")
46+
const dataSettings = {
47+
first: "Jane",
48+
last: "Doe",
49+
}
50+
51+
mockElement.setAttribute("id", nlsConfigElementId)
52+
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
53+
document.body.appendChild(mockElement)
54+
const actual = getNlsConfiguration(global.document)
55+
56+
expect(actual).toStrictEqual(dataSettings)
57+
58+
document.body.removeChild(mockElement)
59+
})
60+
})
61+
})

0 commit comments

Comments
 (0)