mirror of https://github.com/coder/code-server.git
feat: add full test coverage browser/vscode
This commit is contained in:
parent
c0d62da127
commit
79b4e4780d
|
@ -24,13 +24,13 @@ type NlsConfiguration = {
|
||||||
* Helper function to create the path to the bundle
|
* Helper function to create the path to the bundle
|
||||||
* for getNlsConfiguration.
|
* for getNlsConfiguration.
|
||||||
*/
|
*/
|
||||||
export function createBundlePath(_resolvedLanguagePackCoreLocation: string, bundle: string) {
|
export function createBundlePath(_resolvedLanguagePackCoreLocation: string | undefined, bundle: string) {
|
||||||
// NOTE@jsjoeio - this comment was here before me
|
// NOTE@jsjoeio - this comment was here before me
|
||||||
// Refers to operating systems that use a different path separator.
|
// Refers to operating systems that use a different path separator.
|
||||||
// Probably just Windows but we're not sure if "/" breaks on Windows
|
// Probably just Windows but we're not sure if "/" breaks on Windows
|
||||||
// so we'll leave it alone for now.
|
// so we'll leave it alone for now.
|
||||||
// FIXME: Only works if path separators are /.
|
// FIXME: Only works if path separators are /.
|
||||||
return _resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
|
return (_resolvedLanguagePackCoreLocation || "") + "/" + bundle.replace(/\//g, "!") + ".nls.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,20 +72,22 @@ export function getNlsConfiguration(_document: Document, base: string) {
|
||||||
|
|
||||||
type LoadBundleCallback = (_: undefined, result?: string) => void
|
type LoadBundleCallback = (_: undefined, result?: string) => void
|
||||||
|
|
||||||
nlsConfig.loadBundle = (bundle: string, _language: string, cb: LoadBundleCallback): void => {
|
nlsConfig.loadBundle = async (bundle: string, _language: string, cb: LoadBundleCallback): Promise<void> => {
|
||||||
const result = bundles[bundle]
|
const result = bundles[bundle]
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
return cb(undefined, result)
|
return cb(undefined, result)
|
||||||
}
|
}
|
||||||
// FIXME: Only works if path separators are /.
|
|
||||||
const path = createBundlePath(nlsConfig._resolvedLanguagePackCoreLocation || "", bundle)
|
try {
|
||||||
fetch(`${base}/vscode/resource/?path=${encodeURIComponent(path)}`)
|
const path = createBundlePath(nlsConfig._resolvedLanguagePackCoreLocation, bundle)
|
||||||
.then((response) => response.json())
|
const response = await fetch(`${base}/vscode/resource/?path=${encodeURIComponent(path)}`)
|
||||||
.then((json) => {
|
const json = await response.json()
|
||||||
bundles[bundle] = json
|
bundles[bundle] = json
|
||||||
cb(undefined, json)
|
return cb(undefined, json)
|
||||||
})
|
} catch (error) {
|
||||||
.catch(cb)
|
return cb(error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,15 @@
|
||||||
"@types/jsdom": "^16.2.6",
|
"@types/jsdom": "^16.2.6",
|
||||||
"@types/node-fetch": "^2.5.8",
|
"@types/node-fetch": "^2.5.8",
|
||||||
"@types/supertest": "^2.0.10",
|
"@types/supertest": "^2.0.10",
|
||||||
|
"@types/wtfnode": "^0.7.0",
|
||||||
"argon2": "^0.28.0",
|
"argon2": "^0.28.0",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
|
"jest-fetch-mock": "^3.0.3",
|
||||||
"jsdom": "^16.4.0",
|
"jsdom": "^16.4.0",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"playwright": "^1.12.1",
|
"playwright": "^1.12.1",
|
||||||
"supertest": "^6.1.1",
|
"supertest": "^6.1.1",
|
||||||
"ts-jest": "^26.4.4",
|
"ts-jest": "^26.4.4",
|
||||||
"@types/wtfnode": "^0.7.0",
|
|
||||||
"wtfnode": "^0.9.0"
|
"wtfnode": "^0.9.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* @jest-environment jsdom
|
* @jest-environment jsdom
|
||||||
*/
|
*/
|
||||||
|
import fetchMock from "jest-fetch-mock"
|
||||||
import { JSDOM } from "jsdom"
|
import { JSDOM } from "jsdom"
|
||||||
import {
|
import {
|
||||||
getNlsConfiguration,
|
getNlsConfiguration,
|
||||||
|
@ -20,6 +21,11 @@ describe("vscode", () => {
|
||||||
// We use underscores to not confuse with global values
|
// We use underscores to not confuse with global values
|
||||||
const { window: _window } = new JSDOM()
|
const { window: _window } = new JSDOM()
|
||||||
_document = _window.document
|
_document = _window.document
|
||||||
|
fetchMock.enableMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fetchMock.resetMocks()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should throw an error if no nlsConfigElement", () => {
|
it("should throw an error if no nlsConfigElement", () => {
|
||||||
|
@ -60,7 +66,7 @@ describe("vscode", () => {
|
||||||
|
|
||||||
_document.body.removeChild(mockElement)
|
_document.body.removeChild(mockElement)
|
||||||
})
|
})
|
||||||
it("should return have loadBundle property if _resolvedLangaugePackCoreLocation", () => {
|
it("should return and have a loadBundle property if _resolvedLangaugePackCoreLocation", async () => {
|
||||||
const mockElement = _document.createElement("div")
|
const mockElement = _document.createElement("div")
|
||||||
const dataSettings = {
|
const dataSettings = {
|
||||||
locale: "en",
|
locale: "en",
|
||||||
|
@ -76,6 +82,32 @@ describe("vscode", () => {
|
||||||
expect(nlsConfig._resolvedLanguagePackCoreLocation).not.toBe(undefined)
|
expect(nlsConfig._resolvedLanguagePackCoreLocation).not.toBe(undefined)
|
||||||
expect(nlsConfig.loadBundle).not.toBe(undefined)
|
expect(nlsConfig.loadBundle).not.toBe(undefined)
|
||||||
|
|
||||||
|
const mockCallbackFn = jest.fn((_, bundle) => {
|
||||||
|
return bundle
|
||||||
|
})
|
||||||
|
|
||||||
|
fetchMock.mockOnce(JSON.stringify({ key: "hello world" }))
|
||||||
|
// Ensure that load bundle works as expected
|
||||||
|
// by mocking the fetch response and checking that the callback
|
||||||
|
// had the expected value
|
||||||
|
await nlsConfig.loadBundle("hello", "en", mockCallbackFn)
|
||||||
|
expect(mockCallbackFn).toHaveBeenCalledTimes(1)
|
||||||
|
expect(mockCallbackFn).toHaveBeenCalledWith(undefined, { key: "hello world" })
|
||||||
|
|
||||||
|
// Call it again to ensure it loads from the cache
|
||||||
|
// it should return the same value
|
||||||
|
await nlsConfig.loadBundle("hello", "en", mockCallbackFn)
|
||||||
|
expect(mockCallbackFn).toHaveBeenCalledTimes(2)
|
||||||
|
expect(mockCallbackFn).toHaveBeenCalledWith(undefined, { key: "hello world" })
|
||||||
|
|
||||||
|
fetchMock.mockReject(new Error("fake error message"))
|
||||||
|
const mockCallbackFn2 = jest.fn((error) => error)
|
||||||
|
// Call it for a different bundle and mock a failed fetch call
|
||||||
|
// to ensure we get the expected error
|
||||||
|
const error = await nlsConfig.loadBundle("goodbye", "es", mockCallbackFn2)
|
||||||
|
expect(error.message).toEqual("fake error message")
|
||||||
|
|
||||||
|
// Clean up
|
||||||
_document.body.removeChild(mockElement)
|
_document.body.removeChild(mockElement)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -87,6 +119,13 @@ describe("vscode", () => {
|
||||||
const actual = createBundlePath(_resolvedLangaugePackCoreLocation, bundle)
|
const actual = createBundlePath(_resolvedLangaugePackCoreLocation, bundle)
|
||||||
expect(actual).toBe(expected)
|
expect(actual).toBe(expected)
|
||||||
})
|
})
|
||||||
|
it("should return the correct path (even if _resolvedLangaugePackCoreLocation is undefined)", () => {
|
||||||
|
const _resolvedLangaugePackCoreLocation = undefined
|
||||||
|
const bundle = "/bundle.js"
|
||||||
|
const expected = "/!bundle.js.nls.json"
|
||||||
|
const actual = createBundlePath(_resolvedLangaugePackCoreLocation, bundle)
|
||||||
|
expect(actual).toBe(expected)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
describe("setBodyBackgroundToThemeBackgroundColor", () => {
|
describe("setBodyBackgroundToThemeBackgroundColor", () => {
|
||||||
let _document: Document
|
let _document: Document
|
||||||
|
@ -228,11 +267,6 @@ describe("vscode", () => {
|
||||||
},
|
},
|
||||||
recordStats: true,
|
recordStats: true,
|
||||||
|
|
||||||
// TODO@jsjoeio address trustedTypesPolicy part
|
|
||||||
// might need to look up types
|
|
||||||
// and find a way to test the function
|
|
||||||
// maybe extract function into function
|
|
||||||
// and test manually
|
|
||||||
trustedTypesPolicy: undefined,
|
trustedTypesPolicy: undefined,
|
||||||
"vs/nls": {
|
"vs/nls": {
|
||||||
availableLanguages: {},
|
availableLanguages: {},
|
||||||
|
@ -280,6 +314,11 @@ describe("vscode", () => {
|
||||||
|
|
||||||
expect(loader.trustedTypesPolicy).not.toBe(undefined)
|
expect(loader.trustedTypesPolicy).not.toBe(undefined)
|
||||||
expect(loader.trustedTypesPolicy.name).toBe("amdLoader")
|
expect(loader.trustedTypesPolicy.name).toBe("amdLoader")
|
||||||
|
|
||||||
|
// Check that we can actually create a script URL
|
||||||
|
// using the createScriptURL on the loader object
|
||||||
|
const scriptUrl = loader.trustedTypesPolicy.createScriptURL("http://localhost/foo.js")
|
||||||
|
expect(scriptUrl).toBe("http://localhost/foo.js")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe("_createScriptURL", () => {
|
describe("_createScriptURL", () => {
|
||||||
|
|
|
@ -1757,6 +1757,13 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||||
|
|
||||||
|
cross-fetch@^3.0.4:
|
||||||
|
version "3.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39"
|
||||||
|
integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==
|
||||||
|
dependencies:
|
||||||
|
node-fetch "2.6.1"
|
||||||
|
|
||||||
cross-spawn@^6.0.0:
|
cross-spawn@^6.0.0:
|
||||||
version "6.0.5"
|
version "6.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||||
|
@ -2800,6 +2807,14 @@ jest-environment-node@^26.6.2:
|
||||||
jest-mock "^26.6.2"
|
jest-mock "^26.6.2"
|
||||||
jest-util "^26.6.2"
|
jest-util "^26.6.2"
|
||||||
|
|
||||||
|
jest-fetch-mock@^3.0.3:
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz#31749c456ae27b8919d69824f1c2bd85fe0a1f3b"
|
||||||
|
integrity sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==
|
||||||
|
dependencies:
|
||||||
|
cross-fetch "^3.0.4"
|
||||||
|
promise-polyfill "^8.1.3"
|
||||||
|
|
||||||
jest-get-type@^26.3.0:
|
jest-get-type@^26.3.0:
|
||||||
version "26.3.0"
|
version "26.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
|
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
|
||||||
|
@ -3418,7 +3433,7 @@ node-addon-api@^3.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161"
|
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161"
|
||||||
integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==
|
integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==
|
||||||
|
|
||||||
node-fetch@^2.6.1:
|
node-fetch@2.6.1, node-fetch@^2.6.1:
|
||||||
version "2.6.1"
|
version "2.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||||
|
@ -3762,6 +3777,11 @@ progress@^2.0.3:
|
||||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||||
|
|
||||||
|
promise-polyfill@^8.1.3:
|
||||||
|
version "8.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.0.tgz#367394726da7561457aba2133c9ceefbd6267da0"
|
||||||
|
integrity sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g==
|
||||||
|
|
||||||
prompts@^2.0.1:
|
prompts@^2.0.1:
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7"
|
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7"
|
||||||
|
|
Loading…
Reference in New Issue