版博士V2.0程序
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

434 строки
9.5 KiB

  1. import { Console } from 'node:console';
  2. import { importModule } from 'local-pkg';
  3. var node = {
  4. name: "node",
  5. async setup(global) {
  6. global.console.Console = Console;
  7. return {
  8. teardown(global2) {
  9. delete global2.console.Console;
  10. }
  11. };
  12. }
  13. };
  14. const LIVING_KEYS = [
  15. "DOMException",
  16. "URL",
  17. "URLSearchParams",
  18. "EventTarget",
  19. "NamedNodeMap",
  20. "Node",
  21. "Attr",
  22. "Element",
  23. "DocumentFragment",
  24. "DOMImplementation",
  25. "Document",
  26. "XMLDocument",
  27. "CharacterData",
  28. "Text",
  29. "CDATASection",
  30. "ProcessingInstruction",
  31. "Comment",
  32. "DocumentType",
  33. "NodeList",
  34. "RadioNodeList",
  35. "HTMLCollection",
  36. "HTMLOptionsCollection",
  37. "DOMStringMap",
  38. "DOMTokenList",
  39. "StyleSheetList",
  40. "HTMLElement",
  41. "HTMLHeadElement",
  42. "HTMLTitleElement",
  43. "HTMLBaseElement",
  44. "HTMLLinkElement",
  45. "HTMLMetaElement",
  46. "HTMLStyleElement",
  47. "HTMLBodyElement",
  48. "HTMLHeadingElement",
  49. "HTMLParagraphElement",
  50. "HTMLHRElement",
  51. "HTMLPreElement",
  52. "HTMLUListElement",
  53. "HTMLOListElement",
  54. "HTMLLIElement",
  55. "HTMLMenuElement",
  56. "HTMLDListElement",
  57. "HTMLDivElement",
  58. "HTMLAnchorElement",
  59. "HTMLAreaElement",
  60. "HTMLBRElement",
  61. "HTMLButtonElement",
  62. "HTMLCanvasElement",
  63. "HTMLDataElement",
  64. "HTMLDataListElement",
  65. "HTMLDetailsElement",
  66. "HTMLDialogElement",
  67. "HTMLDirectoryElement",
  68. "HTMLFieldSetElement",
  69. "HTMLFontElement",
  70. "HTMLFormElement",
  71. "HTMLHtmlElement",
  72. "HTMLImageElement",
  73. "HTMLInputElement",
  74. "HTMLLabelElement",
  75. "HTMLLegendElement",
  76. "HTMLMapElement",
  77. "HTMLMarqueeElement",
  78. "HTMLMediaElement",
  79. "HTMLMeterElement",
  80. "HTMLModElement",
  81. "HTMLOptGroupElement",
  82. "HTMLOptionElement",
  83. "HTMLOutputElement",
  84. "HTMLPictureElement",
  85. "HTMLProgressElement",
  86. "HTMLQuoteElement",
  87. "HTMLScriptElement",
  88. "HTMLSelectElement",
  89. "HTMLSlotElement",
  90. "HTMLSourceElement",
  91. "HTMLSpanElement",
  92. "HTMLTableCaptionElement",
  93. "HTMLTableCellElement",
  94. "HTMLTableColElement",
  95. "HTMLTableElement",
  96. "HTMLTimeElement",
  97. "HTMLTableRowElement",
  98. "HTMLTableSectionElement",
  99. "HTMLTemplateElement",
  100. "HTMLTextAreaElement",
  101. "HTMLUnknownElement",
  102. "HTMLFrameElement",
  103. "HTMLFrameSetElement",
  104. "HTMLIFrameElement",
  105. "HTMLEmbedElement",
  106. "HTMLObjectElement",
  107. "HTMLParamElement",
  108. "HTMLVideoElement",
  109. "HTMLAudioElement",
  110. "HTMLTrackElement",
  111. "HTMLFormControlsCollection",
  112. "SVGElement",
  113. "SVGGraphicsElement",
  114. "SVGSVGElement",
  115. "SVGTitleElement",
  116. "SVGAnimatedString",
  117. "SVGNumber",
  118. "SVGStringList",
  119. "Event",
  120. "CloseEvent",
  121. "CustomEvent",
  122. "MessageEvent",
  123. "ErrorEvent",
  124. "HashChangeEvent",
  125. "PopStateEvent",
  126. "StorageEvent",
  127. "ProgressEvent",
  128. "PageTransitionEvent",
  129. "UIEvent",
  130. "FocusEvent",
  131. "InputEvent",
  132. "MouseEvent",
  133. "KeyboardEvent",
  134. "TouchEvent",
  135. "CompositionEvent",
  136. "WheelEvent",
  137. "BarProp",
  138. "External",
  139. "Location",
  140. "History",
  141. "Screen",
  142. "Crypto",
  143. "Performance",
  144. "Navigator",
  145. "PluginArray",
  146. "MimeTypeArray",
  147. "Plugin",
  148. "MimeType",
  149. "FileReader",
  150. "Blob",
  151. "File",
  152. "FileList",
  153. "ValidityState",
  154. "DOMParser",
  155. "XMLSerializer",
  156. "FormData",
  157. "XMLHttpRequestEventTarget",
  158. "XMLHttpRequestUpload",
  159. "XMLHttpRequest",
  160. "WebSocket",
  161. "NodeFilter",
  162. "NodeIterator",
  163. "TreeWalker",
  164. "AbstractRange",
  165. "Range",
  166. "StaticRange",
  167. "Selection",
  168. "Storage",
  169. "CustomElementRegistry",
  170. "ShadowRoot",
  171. "MutationObserver",
  172. "MutationRecord",
  173. "Headers",
  174. "AbortController",
  175. "AbortSignal",
  176. "ArrayBuffer",
  177. "Image",
  178. "Audio",
  179. "Option"
  180. ];
  181. const OTHER_KEYS = [
  182. "addEventListener",
  183. "alert",
  184. "atob",
  185. "blur",
  186. "btoa",
  187. "cancelAnimationFrame",
  188. "close",
  189. "confirm",
  190. "createPopup",
  191. "dispatchEvent",
  192. "document",
  193. "focus",
  194. "frames",
  195. "getComputedStyle",
  196. "history",
  197. "innerHeight",
  198. "innerWidth",
  199. "length",
  200. "location",
  201. "matchMedia",
  202. "moveBy",
  203. "moveTo",
  204. "name",
  205. "navigator",
  206. "open",
  207. "outerHeight",
  208. "outerWidth",
  209. "pageXOffset",
  210. "pageYOffset",
  211. "parent",
  212. "postMessage",
  213. "print",
  214. "prompt",
  215. "removeEventListener",
  216. "requestAnimationFrame",
  217. "resizeBy",
  218. "resizeTo",
  219. "screen",
  220. "screenLeft",
  221. "screenTop",
  222. "screenX",
  223. "screenY",
  224. "scroll",
  225. "scrollBy",
  226. "scrollLeft",
  227. "scrollTo",
  228. "scrollTop",
  229. "scrollX",
  230. "scrollY",
  231. "self",
  232. "stop",
  233. "top",
  234. "Window",
  235. "window"
  236. ];
  237. const KEYS = LIVING_KEYS.concat(OTHER_KEYS);
  238. const skipKeys = [
  239. "window",
  240. "self",
  241. "top",
  242. "parent"
  243. ];
  244. function getWindowKeys(global, win) {
  245. const keys = new Set(KEYS.concat(Object.getOwnPropertyNames(win)).filter((k) => {
  246. if (skipKeys.includes(k))
  247. return false;
  248. if (k in global)
  249. return KEYS.includes(k);
  250. return true;
  251. }));
  252. return keys;
  253. }
  254. function isClassLikeName(name) {
  255. return name[0] === name[0].toUpperCase();
  256. }
  257. function populateGlobal(global, win, options = {}) {
  258. const { bindFunctions = false } = options;
  259. const keys = getWindowKeys(global, win);
  260. const originals = /* @__PURE__ */ new Map();
  261. const overrideObject = /* @__PURE__ */ new Map();
  262. for (const key of keys) {
  263. const boundFunction = bindFunctions && typeof win[key] === "function" && !isClassLikeName(key) && win[key].bind(win);
  264. if (KEYS.includes(key) && key in global)
  265. originals.set(key, global[key]);
  266. Object.defineProperty(global, key, {
  267. get() {
  268. if (overrideObject.has(key))
  269. return overrideObject.get(key);
  270. if (boundFunction)
  271. return boundFunction;
  272. return win[key];
  273. },
  274. set(v) {
  275. overrideObject.set(key, v);
  276. },
  277. configurable: true
  278. });
  279. }
  280. global.window = global;
  281. global.self = global;
  282. global.top = global;
  283. global.parent = global;
  284. if (global.global)
  285. global.global = global;
  286. if (global.document && global.document.defaultView) {
  287. Object.defineProperty(global.document, "defaultView", {
  288. get: () => global,
  289. enumerable: true,
  290. configurable: true
  291. });
  292. }
  293. skipKeys.forEach((k) => keys.add(k));
  294. return {
  295. keys,
  296. skipKeys,
  297. originals
  298. };
  299. }
  300. function catchWindowErrors(window) {
  301. let userErrorListenerCount = 0;
  302. function throwUnhandlerError(e) {
  303. if (userErrorListenerCount === 0 && e.error != null)
  304. process.emit("uncaughtException", e.error);
  305. }
  306. const addEventListener = window.addEventListener.bind(window);
  307. const removeEventListener = window.removeEventListener.bind(window);
  308. window.addEventListener("error", throwUnhandlerError);
  309. window.addEventListener = function(...args) {
  310. if (args[0] === "error")
  311. userErrorListenerCount++;
  312. return addEventListener.apply(this, args);
  313. };
  314. window.removeEventListener = function(...args) {
  315. if (args[0] === "error" && userErrorListenerCount)
  316. userErrorListenerCount--;
  317. return removeEventListener.apply(this, args);
  318. };
  319. return function clearErrorHandlers() {
  320. window.removeEventListener("error", throwUnhandlerError);
  321. };
  322. }
  323. var jsdom = {
  324. name: "jsdom",
  325. async setup(global, { jsdom = {} }) {
  326. const {
  327. CookieJar,
  328. JSDOM,
  329. ResourceLoader,
  330. VirtualConsole
  331. } = await importModule("jsdom");
  332. const {
  333. html = "<!DOCTYPE html>",
  334. userAgent,
  335. url = "http://localhost:3000",
  336. contentType = "text/html",
  337. pretendToBeVisual = true,
  338. includeNodeLocations = false,
  339. runScripts = "dangerously",
  340. resources,
  341. console = false,
  342. cookieJar = false,
  343. ...restOptions
  344. } = jsdom;
  345. const dom = new JSDOM(
  346. html,
  347. {
  348. pretendToBeVisual,
  349. resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0),
  350. runScripts,
  351. url,
  352. virtualConsole: console && global.console ? new VirtualConsole().sendTo(global.console) : void 0,
  353. cookieJar: cookieJar ? new CookieJar() : void 0,
  354. includeNodeLocations,
  355. contentType,
  356. userAgent,
  357. ...restOptions
  358. }
  359. );
  360. const { keys, originals } = populateGlobal(global, dom.window, { bindFunctions: true });
  361. const clearWindowErrors = catchWindowErrors(global);
  362. return {
  363. teardown(global2) {
  364. clearWindowErrors();
  365. dom.window.close();
  366. keys.forEach((key) => delete global2[key]);
  367. originals.forEach((v, k) => global2[k] = v);
  368. }
  369. };
  370. }
  371. };
  372. var happy = {
  373. name: "happy-dom",
  374. async setup(global) {
  375. const { Window, GlobalWindow } = await importModule("happy-dom");
  376. const win = new (GlobalWindow || Window)();
  377. const { keys, originals } = populateGlobal(global, win, { bindFunctions: true });
  378. return {
  379. teardown(global2) {
  380. win.happyDOM.cancelAsync();
  381. keys.forEach((key) => delete global2[key]);
  382. originals.forEach((v, k) => global2[k] = v);
  383. }
  384. };
  385. }
  386. };
  387. var edge = {
  388. name: "edge-runtime",
  389. async setup(global) {
  390. const { EdgeVM } = await importModule("@edge-runtime/vm");
  391. const vm = new EdgeVM({
  392. extend: (context) => {
  393. context.global = context;
  394. context.Buffer = Buffer;
  395. return context;
  396. }
  397. });
  398. const { keys, originals } = populateGlobal(global, vm.context, { bindFunctions: true });
  399. return {
  400. teardown(global2) {
  401. keys.forEach((key) => delete global2[key]);
  402. originals.forEach((v, k) => global2[k] = v);
  403. }
  404. };
  405. }
  406. };
  407. const environments = {
  408. node,
  409. jsdom,
  410. "happy-dom": happy,
  411. "edge-runtime": edge
  412. };
  413. const envPackageNames = {
  414. "jsdom": "jsdom",
  415. "happy-dom": "happy-dom",
  416. "edge-runtime": "@edge-runtime/vm"
  417. };
  418. const getEnvPackageName = (env) => {
  419. if (env === "node")
  420. return null;
  421. if (env in envPackageNames)
  422. return envPackageNames[env];
  423. return `vitest-environment-${env}`;
  424. };
  425. export { environments as e, getEnvPackageName as g, populateGlobal as p };