Skip to content

Commit d833967

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 aa08f84 commit d833967

File tree

2 files changed

+120
-4
lines changed

2 files changed

+120
-4
lines changed

src/browser/pages/vscode.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,54 @@ const options = getOptions()
55
// TODO: Add proper types.
66
/* eslint-disable @typescript-eslint/no-explicit-any */
77

8-
let nlsConfig: any
8+
export const nlsConfigElementId = "vscode-remote-nls-configuration"
9+
10+
type NlsConfiguration = {
11+
locale: string
12+
availableLanguages: { [key: string]: string } | {}
13+
_languagePackId?: string
14+
_translationsConfigFile?: string
15+
_cacheRoot?: string
16+
_resolvedLanguagePackCoreLocation?: string
17+
_corruptedFile?: string
18+
_languagePackSupport?: boolean
19+
loadBundle?: any
20+
}
21+
22+
/**
23+
* A helper function to get the NLS Configuration settings.
24+
*
25+
* This is used by VSCode for localizations (i.e. changing
26+
* the display language).
27+
**/
28+
export function getNlsConfiguration(document: Document) {
29+
const nlsConfigElement = document?.getElementById(nlsConfigElementId)
30+
const nlsConfig = nlsConfigElement?.getAttribute("data-settings")
31+
32+
if (!document || !nlsConfigElement || !nlsConfig) {
33+
return undefined
34+
}
35+
36+
try {
37+
return JSON.parse(nlsConfig) as NlsConfiguration
38+
} catch (error) {
39+
console.error("[vscode] Failed to read or parse the NLS configuration.", error)
40+
return undefined
41+
}
42+
}
43+
44+
let nlsConfig: NlsConfiguration | undefined
945
try {
10-
nlsConfig = JSON.parse(document.getElementById("vscode-remote-nls-configuration")!.getAttribute("data-settings")!)
11-
if (nlsConfig._resolvedLanguagePackCoreLocation) {
46+
nlsConfig = getNlsConfiguration(document)
47+
if (nlsConfig?._resolvedLanguagePackCoreLocation) {
1248
const bundles = Object.create(null)
1349
nlsConfig.loadBundle = (bundle: any, _language: any, cb: any): void => {
1450
const result = bundles[bundle]
1551
if (result) {
1652
return cb(undefined, result)
1753
}
1854
// FIXME: Only works if path separators are /.
19-
const path = nlsConfig._resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
55+
const path = nlsConfig?._resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
2056
fetch(`${options.base}/vscode/resource/?path=${encodeURIComponent(path)}`)
2157
.then((response) => response.json())
2258
.then((json) => {

test/unit/browser/vscode.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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 return undefined if Document is undefined", () => {
15+
const actual = getNlsConfiguration(undefined as any as Document)
16+
const expected = undefined
17+
18+
expect(actual).toBe(expected)
19+
})
20+
it("should return undefined if no nlsConfigElement", () => {
21+
const actual = getNlsConfiguration(global.document)
22+
const expected = undefined
23+
24+
expect(actual).toBe(expected)
25+
})
26+
it("should return undefined if no nlsConfig", () => {
27+
const mockElement = document.createElement("div")
28+
mockElement.setAttribute("id", nlsConfigElementId)
29+
document.body.appendChild(mockElement)
30+
31+
const actual = getNlsConfiguration(document)
32+
const expected = undefined
33+
34+
expect(actual).toBe(expected)
35+
36+
document.body.removeChild(mockElement)
37+
})
38+
it("should log an error if it can't parse the nlsConfig", () => {
39+
const consoleError = console.error
40+
let errorMessage = ""
41+
42+
console.error = (x) => {
43+
errorMessage = x
44+
}
45+
46+
const mockElement = document.createElement("div")
47+
const dataSettings = {
48+
first: "Jane",
49+
last: "Doe",
50+
}
51+
52+
mockElement.setAttribute("id", nlsConfigElementId)
53+
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings) + ",")
54+
document.body.appendChild(mockElement)
55+
56+
getNlsConfiguration(global.document)
57+
58+
expect(errorMessage).toBe("[vscode] Failed to read or parse the NLS configuration.")
59+
60+
console.error = consoleError
61+
document.body.removeChild(mockElement)
62+
})
63+
it("should return the correct configuration", () => {
64+
const mockElement = document.createElement("div")
65+
const dataSettings = {
66+
first: "Jane",
67+
last: "Doe",
68+
}
69+
70+
mockElement.setAttribute("id", nlsConfigElementId)
71+
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
72+
document.body.appendChild(mockElement)
73+
const actual = getNlsConfiguration(global.document)
74+
75+
expect(actual).toStrictEqual(dataSettings)
76+
77+
document.body.removeChild(mockElement)
78+
})
79+
})
80+
})

0 commit comments

Comments
 (0)