mirror of
https://github.com/coder/code-server.git
synced 2024-12-27 19:56:57 +03:00
Merge pull request #3760 from cdr/jsjoeio-add-vscode-test
feat: add registerRequireOnSelf on function
This commit is contained in:
commit
7b8cd25c0c
@ -1,10 +1,8 @@
|
|||||||
import { getOptions } from "../../common/util"
|
import { getOptions, Options } from "../../common/util"
|
||||||
import "../register"
|
import "../register"
|
||||||
|
|
||||||
const options = getOptions()
|
// TODO@jsjoeio: Add proper types.
|
||||||
|
type FixMeLater = any
|
||||||
// TODO: Add proper types.
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
||||||
|
|
||||||
// NOTE@jsjoeio
|
// NOTE@jsjoeio
|
||||||
// This lives here ../../../lib/vscode/src/vs/base/common/platform.ts#L106
|
// This lives here ../../../lib/vscode/src/vs/base/common/platform.ts#L106
|
||||||
@ -19,7 +17,20 @@ type NlsConfiguration = {
|
|||||||
_resolvedLanguagePackCoreLocation?: string
|
_resolvedLanguagePackCoreLocation?: string
|
||||||
_corruptedFile?: string
|
_corruptedFile?: string
|
||||||
_languagePackSupport?: boolean
|
_languagePackSupport?: boolean
|
||||||
loadBundle?: any
|
loadBundle?: FixMeLater
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to create the path to the bundle
|
||||||
|
* for getNlsConfiguration.
|
||||||
|
*/
|
||||||
|
export function createBundlePath(_resolvedLanguagePackCoreLocation: string, bundle: string) {
|
||||||
|
// NOTE@jsjoeio - this comment was here before me
|
||||||
|
// Refers to operating systems that use a different path separator.
|
||||||
|
// Probably just Windows but we're not sure if "/" breaks on Windows
|
||||||
|
// so we'll leave it alone for now.
|
||||||
|
// FIXME: Only works if path separators are /.
|
||||||
|
return _resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,14 +41,10 @@ type NlsConfiguration = {
|
|||||||
*
|
*
|
||||||
* Make sure to wrap this in a try/catch block when you call it.
|
* Make sure to wrap this in a try/catch block when you call it.
|
||||||
**/
|
**/
|
||||||
export function getNlsConfiguration(document: Document) {
|
export function getNlsConfiguration(_document: Document, base: string) {
|
||||||
const errorMsgPrefix = "[vscode]"
|
const errorMsgPrefix = "[vscode]"
|
||||||
const nlsConfigElement = document?.getElementById(nlsConfigElementId)
|
const nlsConfigElement = _document?.getElementById(nlsConfigElementId)
|
||||||
const nlsConfig = nlsConfigElement?.getAttribute("data-settings")
|
const dataSettings = nlsConfigElement?.getAttribute("data-settings")
|
||||||
|
|
||||||
if (!document) {
|
|
||||||
throw new Error(`${errorMsgPrefix} Could not parse NLS configuration. document is undefined.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nlsConfigElement) {
|
if (!nlsConfigElement) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -45,27 +52,34 @@ export function getNlsConfiguration(document: Document) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nlsConfig) {
|
if (!dataSettings) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`,
|
`${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.parse(nlsConfig) as NlsConfiguration
|
const nlsConfig = JSON.parse(dataSettings) as NlsConfiguration
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const nlsConfig = getNlsConfiguration(document)
|
|
||||||
if (nlsConfig._resolvedLanguagePackCoreLocation) {
|
if (nlsConfig._resolvedLanguagePackCoreLocation) {
|
||||||
const bundles = Object.create(null)
|
// NOTE@jsjoeio
|
||||||
nlsConfig.loadBundle = (bundle: any, _language: any, cb: any): void => {
|
// Not sure why we use Object.create(null) instead of {}
|
||||||
|
// They are not the same
|
||||||
|
// See: https://stackoverflow.com/a/15518712/3015595
|
||||||
|
// We copied this from ../../../lib/vscode/src/bootstrap.js#L143
|
||||||
|
const bundles: {
|
||||||
|
[key: string]: string
|
||||||
|
} = Object.create(null)
|
||||||
|
|
||||||
|
type LoadBundleCallback = (_: undefined, result?: string) => void
|
||||||
|
|
||||||
|
nlsConfig.loadBundle = (bundle: string, _language: string, cb: LoadBundleCallback): 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 /.
|
// FIXME: Only works if path separators are /.
|
||||||
const path = nlsConfig._resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
|
const path = createBundlePath(nlsConfig._resolvedLanguagePackCoreLocation || "", bundle)
|
||||||
fetch(`${options.base}/vscode/resource/?path=${encodeURIComponent(path)}`)
|
fetch(`${base}/vscode/resource/?path=${encodeURIComponent(path)}`)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((json) => {
|
.then((json) => {
|
||||||
bundles[bundle] = json
|
bundles[bundle] = json
|
||||||
@ -74,17 +88,61 @@ try {
|
|||||||
.catch(cb)
|
.catch(cb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;(self.require as any) = {
|
|
||||||
// Without the full URL VS Code will try to load file://.
|
return nlsConfig
|
||||||
baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`,
|
}
|
||||||
recordStats: true,
|
|
||||||
// TODO: There don't appear to be any types for trustedTypes yet.
|
type GetLoaderParams = {
|
||||||
trustedTypesPolicy: (window as any).trustedTypes?.createPolicy("amdLoader", {
|
nlsConfig: NlsConfiguration
|
||||||
createScriptURL(value: string): string {
|
options: Options
|
||||||
if (value.startsWith(window.location.origin)) {
|
_window: Window
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link to types in the loader source repo
|
||||||
|
* https://github.com/microsoft/vscode-loader/blob/main/src/loader.d.ts#L280
|
||||||
|
*/
|
||||||
|
type Loader = {
|
||||||
|
baseUrl: string
|
||||||
|
recordStats: boolean
|
||||||
|
// TODO@jsjoeio: There don't appear to be any types for trustedTypes yet.
|
||||||
|
trustedTypesPolicy: FixMeLater
|
||||||
|
paths: {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
"vs/nls": NlsConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function which creates a script url if the value
|
||||||
|
* is valid.
|
||||||
|
*
|
||||||
|
* Extracted into a function to make it easier to test
|
||||||
|
*/
|
||||||
|
export function _createScriptURL(value: string, origin: string): string {
|
||||||
|
if (value.startsWith(origin)) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
throw new Error(`Invalid script url: ${value}`)
|
throw new Error(`Invalid script url: ${value}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function to get the require loader
|
||||||
|
*
|
||||||
|
* This used by VSCode/code-server
|
||||||
|
* to load files.
|
||||||
|
*
|
||||||
|
* We extracted the logic into a function so that
|
||||||
|
* it's easier to test.
|
||||||
|
**/
|
||||||
|
export function getConfigurationForLoader({ nlsConfig, options, _window }: GetLoaderParams) {
|
||||||
|
const loader: Loader = {
|
||||||
|
// Without the full URL VS Code will try to load file://.
|
||||||
|
baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`,
|
||||||
|
recordStats: true,
|
||||||
|
trustedTypesPolicy: (_window as FixMeLater).trustedTypes?.createPolicy("amdLoader", {
|
||||||
|
createScriptURL(value: string): string {
|
||||||
|
return _createScriptURL(value, window.location.origin)
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
paths: {
|
paths: {
|
||||||
@ -100,25 +158,16 @@ try {
|
|||||||
},
|
},
|
||||||
"vs/nls": nlsConfig,
|
"vs/nls": nlsConfig,
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
return loader
|
||||||
/* Probably fine. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setBodyBackgroundToThemeBackgroundColor(document: Document, localStorage: Storage) {
|
/**
|
||||||
|
* Sets the body background color to match the theme.
|
||||||
|
*/
|
||||||
|
export function setBodyBackgroundToThemeBackgroundColor(_document: Document, _localStorage: Storage) {
|
||||||
const errorMsgPrefix = "[vscode]"
|
const errorMsgPrefix = "[vscode]"
|
||||||
|
const colorThemeData = _localStorage.getItem("colorThemeData")
|
||||||
if (!document) {
|
|
||||||
throw new Error(`${errorMsgPrefix} Could not set body background to theme background color. Document is undefined.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!localStorage) {
|
|
||||||
throw new Error(
|
|
||||||
`${errorMsgPrefix} Could not set body background to theme background color. localStorage is undefined.`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const colorThemeData = localStorage.getItem("colorThemeData")
|
|
||||||
|
|
||||||
if (!colorThemeData) {
|
if (!colorThemeData) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -155,14 +204,48 @@ export function setBodyBackgroundToThemeBackgroundColor(document: Document, loca
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.style.background = editorBgColor
|
_document.body.style.background = editorBgColor
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function to encapsulate all the
|
||||||
|
* logic used in this file.
|
||||||
|
*
|
||||||
|
* We purposely include all of this in a single function
|
||||||
|
* so that it's easier to test.
|
||||||
|
*/
|
||||||
|
export function main(_document: Document | undefined, _window: Window | undefined, _localStorage: Storage | undefined) {
|
||||||
|
if (!_document) {
|
||||||
|
throw new Error(`document is undefined.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_window) {
|
||||||
|
throw new Error(`window is undefined.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_localStorage) {
|
||||||
|
throw new Error(`localStorage is undefined.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = getOptions()
|
||||||
|
const nlsConfig = getNlsConfiguration(_document, options.base)
|
||||||
|
|
||||||
|
const loader = getConfigurationForLoader({
|
||||||
|
nlsConfig,
|
||||||
|
options,
|
||||||
|
_window,
|
||||||
|
})
|
||||||
|
|
||||||
|
;(self.require as unknown as Loader) = loader
|
||||||
|
|
||||||
|
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
main(document, window, localStorage)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Something went wrong setting the body background to the theme background color.")
|
console.error("[vscode] failed to initialize VS Code")
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
|
@ -5,48 +5,47 @@ import { JSDOM } from "jsdom"
|
|||||||
import {
|
import {
|
||||||
getNlsConfiguration,
|
getNlsConfiguration,
|
||||||
nlsConfigElementId,
|
nlsConfigElementId,
|
||||||
|
getConfigurationForLoader,
|
||||||
setBodyBackgroundToThemeBackgroundColor,
|
setBodyBackgroundToThemeBackgroundColor,
|
||||||
|
_createScriptURL,
|
||||||
|
main,
|
||||||
|
createBundlePath,
|
||||||
} from "../../../../src/browser/pages/vscode"
|
} from "../../../../src/browser/pages/vscode"
|
||||||
|
|
||||||
describe("vscode", () => {
|
describe("vscode", () => {
|
||||||
describe("getNlsConfiguration", () => {
|
describe("getNlsConfiguration", () => {
|
||||||
|
let _document: Document
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const { window } = new JSDOM()
|
// We use underscores to not confuse with global values
|
||||||
global.document = window.document
|
const { window: _window } = new JSDOM()
|
||||||
|
_document = _window.document
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should throw an error if Document is undefined", () => {
|
|
||||||
const errorMsgPrefix = "[vscode]"
|
|
||||||
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. document is undefined.`
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
getNlsConfiguration(undefined as any as Document)
|
|
||||||
}).toThrowError(errorMessage)
|
|
||||||
})
|
|
||||||
it("should throw an error if no nlsConfigElement", () => {
|
it("should throw an error if no nlsConfigElement", () => {
|
||||||
const errorMsgPrefix = "[vscode]"
|
const errorMsgPrefix = "[vscode]"
|
||||||
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Could not find nlsConfigElement with id: ${nlsConfigElementId}`
|
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Could not find nlsConfigElement with id: ${nlsConfigElementId}`
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
getNlsConfiguration(document)
|
getNlsConfiguration(_document, "")
|
||||||
}).toThrowError(errorMessage)
|
}).toThrowError(errorMessage)
|
||||||
})
|
})
|
||||||
it("should throw an error if no nlsConfig", () => {
|
it("should throw an error if no nlsConfig", () => {
|
||||||
const mockElement = document.createElement("div")
|
const mockElement = _document.createElement("div")
|
||||||
mockElement.setAttribute("id", nlsConfigElementId)
|
mockElement.setAttribute("id", nlsConfigElementId)
|
||||||
document.body.appendChild(mockElement)
|
_document.body.appendChild(mockElement)
|
||||||
|
|
||||||
const errorMsgPrefix = "[vscode]"
|
const errorMsgPrefix = "[vscode]"
|
||||||
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`
|
const errorMessage = `${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
getNlsConfiguration(document)
|
getNlsConfiguration(_document, "")
|
||||||
}).toThrowError(errorMessage)
|
}).toThrowError(errorMessage)
|
||||||
|
|
||||||
document.body.removeChild(mockElement)
|
_document.body.removeChild(mockElement)
|
||||||
})
|
})
|
||||||
it("should return the correct configuration", () => {
|
it("should return the correct configuration", () => {
|
||||||
const mockElement = document.createElement("div")
|
const mockElement = _document.createElement("div")
|
||||||
const dataSettings = {
|
const dataSettings = {
|
||||||
first: "Jane",
|
first: "Jane",
|
||||||
last: "Doe",
|
last: "Doe",
|
||||||
@ -54,22 +53,52 @@ describe("vscode", () => {
|
|||||||
|
|
||||||
mockElement.setAttribute("id", nlsConfigElementId)
|
mockElement.setAttribute("id", nlsConfigElementId)
|
||||||
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
|
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
|
||||||
document.body.appendChild(mockElement)
|
_document.body.appendChild(mockElement)
|
||||||
const actual = getNlsConfiguration(global.document)
|
const actual = getNlsConfiguration(_document, "")
|
||||||
|
|
||||||
expect(actual).toStrictEqual(dataSettings)
|
expect(actual).toStrictEqual(dataSettings)
|
||||||
|
|
||||||
document.body.removeChild(mockElement)
|
_document.body.removeChild(mockElement)
|
||||||
|
})
|
||||||
|
it("should return have loadBundle property if _resolvedLangaugePackCoreLocation", () => {
|
||||||
|
const mockElement = _document.createElement("div")
|
||||||
|
const dataSettings = {
|
||||||
|
locale: "en",
|
||||||
|
availableLanguages: ["en", "de"],
|
||||||
|
_resolvedLanguagePackCoreLocation: "./",
|
||||||
|
}
|
||||||
|
|
||||||
|
mockElement.setAttribute("id", nlsConfigElementId)
|
||||||
|
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
|
||||||
|
_document.body.appendChild(mockElement)
|
||||||
|
const nlsConfig = getNlsConfiguration(_document, "")
|
||||||
|
|
||||||
|
expect(nlsConfig._resolvedLanguagePackCoreLocation).not.toBe(undefined)
|
||||||
|
expect(nlsConfig.loadBundle).not.toBe(undefined)
|
||||||
|
|
||||||
|
_document.body.removeChild(mockElement)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("createBundlePath", () => {
|
||||||
|
it("should return the correct path", () => {
|
||||||
|
const _resolvedLangaugePackCoreLocation = "./languages"
|
||||||
|
const bundle = "/bundle.js"
|
||||||
|
const expected = "./languages/!bundle.js.nls.json"
|
||||||
|
const actual = createBundlePath(_resolvedLangaugePackCoreLocation, bundle)
|
||||||
|
expect(actual).toBe(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe("setBodyBackgroundToThemeBackgroundColor", () => {
|
describe("setBodyBackgroundToThemeBackgroundColor", () => {
|
||||||
|
let _document: Document
|
||||||
|
let _localStorage: Storage
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// We need to set the url in the JSDOM constructor
|
// We need to set the url in the JSDOM constructor
|
||||||
// to prevent this error "SecurityError: localStorage is not available for opaque origins"
|
// to prevent this error "SecurityError: localStorage is not available for opaque origins"
|
||||||
// See: https://github.com/jsdom/jsdom/issues/2304#issuecomment-622314949
|
// See: https://github.com/jsdom/jsdom/issues/2304#issuecomment-622314949
|
||||||
const { window } = new JSDOM("", { url: "http://localhost" })
|
const { window: _window } = new JSDOM("", { url: "http://localhost" })
|
||||||
global.document = window.document
|
_document = _window.document
|
||||||
global.localStorage = window.localStorage
|
_localStorage = _window.localStorage
|
||||||
})
|
})
|
||||||
it("should return null", () => {
|
it("should return null", () => {
|
||||||
const test = {
|
const test = {
|
||||||
@ -77,49 +106,31 @@ describe("vscode", () => {
|
|||||||
[`editor.background`]: "#ff3270",
|
[`editor.background`]: "#ff3270",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
localStorage.setItem("colorThemeData", JSON.stringify(test))
|
_localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||||
|
|
||||||
expect(setBodyBackgroundToThemeBackgroundColor(document, localStorage)).toBeNull()
|
expect(setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)).toBeNull()
|
||||||
|
|
||||||
localStorage.removeItem("colorThemeData")
|
_localStorage.removeItem("colorThemeData")
|
||||||
})
|
|
||||||
it("should throw an error if Document is undefined", () => {
|
|
||||||
const errorMsgPrefix = "[vscode]"
|
|
||||||
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Document is undefined.`
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
// @ts-expect-error We need to test when document is undefined
|
|
||||||
setBodyBackgroundToThemeBackgroundColor(undefined, localStorage)
|
|
||||||
}).toThrowError(errorMessage)
|
|
||||||
})
|
|
||||||
it("should throw an error if localStorage is undefined", () => {
|
|
||||||
const errorMsgPrefix = "[vscode]"
|
|
||||||
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. localStorage is undefined.`
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
// @ts-expect-error We need to test when localStorage is undefined
|
|
||||||
setBodyBackgroundToThemeBackgroundColor(document, undefined)
|
|
||||||
}).toThrowError(errorMessage)
|
|
||||||
})
|
})
|
||||||
it("should throw an error if it can't find colorThemeData in localStorage", () => {
|
it("should throw an error if it can't find colorThemeData in localStorage", () => {
|
||||||
const errorMsgPrefix = "[vscode]"
|
const errorMsgPrefix = "[vscode]"
|
||||||
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not find colorThemeData in localStorage.`
|
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not find colorThemeData in localStorage.`
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||||
}).toThrowError(errorMessage)
|
}).toThrowError(errorMessage)
|
||||||
})
|
})
|
||||||
it("should throw an error if there is an error parsing colorThemeData from localStorage", () => {
|
it("should throw an error if there is an error parsing colorThemeData from localStorage", () => {
|
||||||
const errorMsgPrefix = "[vscode]"
|
const errorMsgPrefix = "[vscode]"
|
||||||
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not parse colorThemeData from localStorage.`
|
const errorMessage = `${errorMsgPrefix} Could not set body background to theme background color. Could not parse colorThemeData from localStorage.`
|
||||||
|
|
||||||
localStorage.setItem(
|
_localStorage.setItem(
|
||||||
"colorThemeData",
|
"colorThemeData",
|
||||||
'{"id":"vs-dark max-SS-Cyberpunk-themes-cyberpunk-umbra-color-theme-json","label":"Activate UMBRA protocol","settingsId":"Activate "errorForeground":"#ff3270","foreground":"#ffffff","sideBarTitle.foreground":"#bbbbbb"},"watch\\":::false}',
|
'{"id":"vs-dark max-SS-Cyberpunk-themes-cyberpunk-umbra-color-theme-json","label":"Activate UMBRA protocol","settingsId":"Activate "errorForeground":"#ff3270","foreground":"#ffffff","sideBarTitle.foreground":"#bbbbbb"},"watch\\":::false}',
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||||
}).toThrowError(errorMessage)
|
}).toThrowError(errorMessage)
|
||||||
|
|
||||||
localStorage.removeItem("colorThemeData")
|
localStorage.removeItem("colorThemeData")
|
||||||
@ -131,13 +142,13 @@ describe("vscode", () => {
|
|||||||
const test = {
|
const test = {
|
||||||
id: "hey-joe",
|
id: "hey-joe",
|
||||||
}
|
}
|
||||||
localStorage.setItem("colorThemeData", JSON.stringify(test))
|
_localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||||
}).toThrowError(errorMessage)
|
}).toThrowError(errorMessage)
|
||||||
|
|
||||||
localStorage.removeItem("colorThemeData")
|
_localStorage.removeItem("colorThemeData")
|
||||||
})
|
})
|
||||||
it("should throw an error if there is no editor.background color", () => {
|
it("should throw an error if there is no editor.background color", () => {
|
||||||
const errorMsgPrefix = "[vscode]"
|
const errorMsgPrefix = "[vscode]"
|
||||||
@ -149,13 +160,13 @@ describe("vscode", () => {
|
|||||||
editor: "#fff",
|
editor: "#fff",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
localStorage.setItem("colorThemeData", JSON.stringify(test))
|
_localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||||
}).toThrowError(errorMessage)
|
}).toThrowError(errorMessage)
|
||||||
|
|
||||||
localStorage.removeItem("colorThemeData")
|
_localStorage.removeItem("colorThemeData")
|
||||||
})
|
})
|
||||||
it("should set the body background to the editor background color", () => {
|
it("should set the body background to the editor background color", () => {
|
||||||
const test = {
|
const test = {
|
||||||
@ -163,16 +174,188 @@ describe("vscode", () => {
|
|||||||
[`editor.background`]: "#ff3270",
|
[`editor.background`]: "#ff3270",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
localStorage.setItem("colorThemeData", JSON.stringify(test))
|
_localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||||
|
|
||||||
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
|
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
|
||||||
|
|
||||||
// When the body.style.backgroundColor is set using hex
|
// When the body.style.backgroundColor is set using hex
|
||||||
// it is converted to rgb
|
// it is converted to rgb
|
||||||
// which is why we use that in the assertion
|
// which is why we use that in the assertion
|
||||||
expect(document.body.style.backgroundColor).toBe("rgb(255, 50, 112)")
|
expect(_document.body.style.backgroundColor).toBe("rgb(255, 50, 112)")
|
||||||
|
|
||||||
localStorage.removeItem("colorThemeData")
|
_localStorage.removeItem("colorThemeData")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("getConfigurationForLoader", () => {
|
||||||
|
let _window: Window
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const { window: __window } = new JSDOM()
|
||||||
|
// @ts-expect-error the Window from JSDOM is not exactly the same as Window
|
||||||
|
// so we expect an error here
|
||||||
|
_window = __window
|
||||||
|
})
|
||||||
|
it("should return a loader object (with undefined trustedTypesPolicy)", () => {
|
||||||
|
const options = {
|
||||||
|
base: ".",
|
||||||
|
csStaticBase: "/",
|
||||||
|
logLevel: 1,
|
||||||
|
}
|
||||||
|
const nlsConfig = {
|
||||||
|
first: "Jane",
|
||||||
|
last: "Doe",
|
||||||
|
locale: "en",
|
||||||
|
availableLanguages: {},
|
||||||
|
}
|
||||||
|
const loader = getConfigurationForLoader({
|
||||||
|
options,
|
||||||
|
_window,
|
||||||
|
nlsConfig: nlsConfig,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(loader).toStrictEqual({
|
||||||
|
baseUrl: "http://localhost//lib/vscode/out",
|
||||||
|
paths: {
|
||||||
|
"iconv-lite-umd": "../node_modules/iconv-lite-umd/lib/iconv-lite-umd.js",
|
||||||
|
jschardet: "../node_modules/jschardet/dist/jschardet.min.js",
|
||||||
|
"tas-client-umd": "../node_modules/tas-client-umd/lib/tas-client-umd.js",
|
||||||
|
"vscode-oniguruma": "../node_modules/vscode-oniguruma/release/main",
|
||||||
|
"vscode-textmate": "../node_modules/vscode-textmate/release/main",
|
||||||
|
xterm: "../node_modules/xterm/lib/xterm.js",
|
||||||
|
"xterm-addon-search": "../node_modules/xterm-addon-search/lib/xterm-addon-search.js",
|
||||||
|
"xterm-addon-unicode11": "../node_modules/xterm-addon-unicode11/lib/xterm-addon-unicode11.js",
|
||||||
|
"xterm-addon-webgl": "../node_modules/xterm-addon-webgl/lib/xterm-addon-webgl.js",
|
||||||
|
},
|
||||||
|
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,
|
||||||
|
"vs/nls": {
|
||||||
|
availableLanguages: {},
|
||||||
|
first: "Jane",
|
||||||
|
last: "Doe",
|
||||||
|
locale: "en",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
it("should return a loader object with trustedTypesPolicy", () => {
|
||||||
|
interface PolicyOptions {
|
||||||
|
createScriptUrl: (url: string) => string
|
||||||
|
}
|
||||||
|
|
||||||
|
function mockCreatePolicy(policyName: string, options: PolicyOptions) {
|
||||||
|
return {
|
||||||
|
name: policyName,
|
||||||
|
...options,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockFn = jest.fn(mockCreatePolicy)
|
||||||
|
|
||||||
|
// @ts-expect-error we are adding a custom property to window
|
||||||
|
_window.trustedTypes = {
|
||||||
|
createPolicy: mockFn,
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
base: "/",
|
||||||
|
csStaticBase: "/",
|
||||||
|
logLevel: 1,
|
||||||
|
}
|
||||||
|
const nlsConfig = {
|
||||||
|
first: "Jane",
|
||||||
|
last: "Doe",
|
||||||
|
locale: "en",
|
||||||
|
availableLanguages: {},
|
||||||
|
}
|
||||||
|
const loader = getConfigurationForLoader({
|
||||||
|
options,
|
||||||
|
_window,
|
||||||
|
nlsConfig: nlsConfig,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(loader.trustedTypesPolicy).not.toBe(undefined)
|
||||||
|
expect(loader.trustedTypesPolicy.name).toBe("amdLoader")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("_createScriptURL", () => {
|
||||||
|
it("should return the correct url", () => {
|
||||||
|
const url = _createScriptURL("localhost/foo/bar.js", "localhost")
|
||||||
|
|
||||||
|
expect(url).toBe("localhost/foo/bar.js")
|
||||||
|
})
|
||||||
|
it("should throw if the value doesn't start with the origin", () => {
|
||||||
|
expect(() => {
|
||||||
|
_createScriptURL("localhost/foo/bar.js", "coder.com")
|
||||||
|
}).toThrow("Invalid script url: localhost/foo/bar.js")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe("main", () => {
|
||||||
|
let _window: Window
|
||||||
|
let _document: Document
|
||||||
|
let _localStorage: Storage
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// We need to set the url in the JSDOM constructor
|
||||||
|
// to prevent this error "SecurityError: localStorage is not available for opaque origins"
|
||||||
|
// See: https://github.com/jsdom/jsdom/issues/2304#issuecomment-62231494
|
||||||
|
const { window: __window } = new JSDOM("", { url: "http://localhost" })
|
||||||
|
// @ts-expect-error the Window from JSDOM is not exactly the same as Window
|
||||||
|
// so we expect an error here
|
||||||
|
_window = __window
|
||||||
|
_document = __window.document
|
||||||
|
_localStorage = __window.localStorage
|
||||||
|
|
||||||
|
const mockElement = _document.createElement("div")
|
||||||
|
const dataSettings = {
|
||||||
|
first: "Jane",
|
||||||
|
last: "Doe",
|
||||||
|
}
|
||||||
|
|
||||||
|
mockElement.setAttribute("id", nlsConfigElementId)
|
||||||
|
mockElement.setAttribute("data-settings", JSON.stringify(dataSettings))
|
||||||
|
_document.body.appendChild(mockElement)
|
||||||
|
|
||||||
|
const test = {
|
||||||
|
colorMap: {
|
||||||
|
[`editor.background`]: "#ff3270",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_localStorage.setItem("colorThemeData", JSON.stringify(test))
|
||||||
|
})
|
||||||
|
afterEach(() => {
|
||||||
|
_localStorage.removeItem("colorThemeData")
|
||||||
|
})
|
||||||
|
it("should throw if document is missing", () => {
|
||||||
|
expect(() => {
|
||||||
|
main(undefined, _window, _localStorage)
|
||||||
|
}).toThrow("document is undefined.")
|
||||||
|
})
|
||||||
|
it("should throw if window is missing", () => {
|
||||||
|
expect(() => {
|
||||||
|
main(_document, undefined, _localStorage)
|
||||||
|
}).toThrow("window is undefined.")
|
||||||
|
})
|
||||||
|
it("should throw if localStorage is missing", () => {
|
||||||
|
expect(() => {
|
||||||
|
main(_document, _window, undefined)
|
||||||
|
}).toThrow("localStorage is undefined.")
|
||||||
|
})
|
||||||
|
it("should add loader to self.require", () => {
|
||||||
|
main(_document, _window, _localStorage)
|
||||||
|
|
||||||
|
expect(Object.prototype.hasOwnProperty.call(self, "require")).toBe(true)
|
||||||
|
})
|
||||||
|
it("should not throw in browser context", () => {
|
||||||
|
// Assuming we call it in a normal browser context
|
||||||
|
// where everything is defined
|
||||||
|
expect(() => {
|
||||||
|
main(_document, _window, _localStorage)
|
||||||
|
}).not.toThrow()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -468,7 +468,7 @@ describe("pathToFsPath", () => {
|
|||||||
expect(util.pathToFsPath("/C:/far/bo", true)).toBe("C:/far/bo")
|
expect(util.pathToFsPath("/C:/far/bo", true)).toBe("C:/far/bo")
|
||||||
})
|
})
|
||||||
it("should replace / with \\ on Windows", () => {
|
it("should replace / with \\ on Windows", () => {
|
||||||
let ORIGINAL_PLATFORM = process.platform
|
const ORIGINAL_PLATFORM = process.platform
|
||||||
|
|
||||||
Object.defineProperty(process, "platform", {
|
Object.defineProperty(process, "platform", {
|
||||||
value: "win32",
|
value: "win32",
|
||||||
|
Loading…
Reference in New Issue
Block a user