mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix memory leak in unit tests
- Upgrade to jest 28 - Switch to using swc - Use @side/jest-runtime as the jest-runtime Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
2eb585e88e
commit
3664306ac7
18
.swcrc
Normal file
18
.swcrc
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"module": {
|
||||||
|
"type": "commonjs"
|
||||||
|
},
|
||||||
|
"jsc": {
|
||||||
|
"parser": {
|
||||||
|
"syntax": "typescript",
|
||||||
|
"tsx": true,
|
||||||
|
"decorators": true,
|
||||||
|
"dynamicImport": false
|
||||||
|
},
|
||||||
|
"transform": {
|
||||||
|
"legacyDecorator": true,
|
||||||
|
"decoratorMetadata": true
|
||||||
|
},
|
||||||
|
"target": "es2019"
|
||||||
|
}
|
||||||
|
}
|
||||||
27
package.json
27
package.json
@ -59,8 +59,12 @@
|
|||||||
"collectCoverage": false,
|
"collectCoverage": false,
|
||||||
"verbose": true,
|
"verbose": true,
|
||||||
"transform": {
|
"transform": {
|
||||||
"^.+\\.tsx?$": "ts-jest"
|
"^.+\\.(t|j)sx?$": [
|
||||||
|
"@swc/jest"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
"testEnvironment": "jsdom",
|
||||||
|
"resolver": "<rootDir>/src/jest-28-resolver.js",
|
||||||
"moduleNameMapper": {
|
"moduleNameMapper": {
|
||||||
"\\.(css|scss)$": "identity-obj-proxy",
|
"\\.(css|scss)$": "identity-obj-proxy",
|
||||||
"\\.(svg|png|jpg|eot|woff2?|ttf)$": "<rootDir>/__mocks__/assetMock.ts"
|
"\\.(svg|png|jpg|eot|woff2?|ttf)$": "<rootDir>/__mocks__/assetMock.ts"
|
||||||
@ -76,11 +80,7 @@
|
|||||||
"setupFilesAfterEnv": [
|
"setupFilesAfterEnv": [
|
||||||
"<rootDir>/src/jest-after-env.setup.ts"
|
"<rootDir>/src/jest-after-env.setup.ts"
|
||||||
],
|
],
|
||||||
"globals": {
|
"runtime": "@side/jest-runtime"
|
||||||
"ts-jest": {
|
|
||||||
"isolatedModules": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"generateUpdatesFilesForAllChannels": true,
|
"generateUpdatesFilesForAllChannels": true,
|
||||||
@ -208,12 +208,13 @@
|
|||||||
"@hapi/subtext": "^7.0.3",
|
"@hapi/subtext": "^7.0.3",
|
||||||
"@kubernetes/client-node": "^0.16.3",
|
"@kubernetes/client-node": "^0.16.3",
|
||||||
"@material-ui/styles": "^4.11.5",
|
"@material-ui/styles": "^4.11.5",
|
||||||
"@ogre-tools/injectable": "7.1.0",
|
|
||||||
"@ogre-tools/injectable-react": "7.1.0",
|
|
||||||
"@ogre-tools/fp": "7.1.0",
|
"@ogre-tools/fp": "7.1.0",
|
||||||
|
"@ogre-tools/injectable": "7.1.0",
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration": "7.1.0",
|
"@ogre-tools/injectable-extension-for-auto-registration": "7.1.0",
|
||||||
|
"@ogre-tools/injectable-react": "7.1.0",
|
||||||
"@sentry/electron": "^3.0.7",
|
"@sentry/electron": "^3.0.7",
|
||||||
"@sentry/integrations": "^6.19.3",
|
"@sentry/integrations": "^6.19.3",
|
||||||
|
"@side/jest-runtime": "^1.0.0",
|
||||||
"@types/circular-dependency-plugin": "5.0.5",
|
"@types/circular-dependency-plugin": "5.0.5",
|
||||||
"abort-controller": "^3.0.0",
|
"abort-controller": "^3.0.0",
|
||||||
"auto-bind": "^4.0.0",
|
"auto-bind": "^4.0.0",
|
||||||
@ -288,6 +289,8 @@
|
|||||||
"@material-ui/lab": "^4.0.0-alpha.60",
|
"@material-ui/lab": "^4.0.0-alpha.60",
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
|
||||||
"@sentry/types": "^6.19.7",
|
"@sentry/types": "^6.19.7",
|
||||||
|
"@swc/core": "^1.2.197",
|
||||||
|
"@swc/jest": "^0.2.21",
|
||||||
"@testing-library/dom": "^7.31.2",
|
"@testing-library/dom": "^7.31.2",
|
||||||
"@testing-library/jest-dom": "^5.16.4",
|
"@testing-library/jest-dom": "^5.16.4",
|
||||||
"@testing-library/react": "^12.1.5",
|
"@testing-library/react": "^12.1.5",
|
||||||
@ -306,7 +309,7 @@
|
|||||||
"@types/gunzip-maybe": "^1.4.0",
|
"@types/gunzip-maybe": "^1.4.0",
|
||||||
"@types/html-webpack-plugin": "^3.2.6",
|
"@types/html-webpack-plugin": "^3.2.6",
|
||||||
"@types/http-proxy": "^1.17.9",
|
"@types/http-proxy": "^1.17.9",
|
||||||
"@types/jest": "^26.0.24",
|
"@types/jest": "^28.1.1",
|
||||||
"@types/js-yaml": "^4.0.5",
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/jsdom": "^16.2.14",
|
"@types/jsdom": "^16.2.14",
|
||||||
"@types/lodash": "^4.14.181",
|
"@types/lodash": "^4.14.181",
|
||||||
@ -374,10 +377,11 @@
|
|||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"ignore-loader": "^0.1.2",
|
"ignore-loader": "^0.1.2",
|
||||||
"include-media": "^1.4.9",
|
"include-media": "^1.4.9",
|
||||||
"jest": "26.6.3",
|
"jest": "^28.1.1",
|
||||||
"jest-canvas-mock": "^2.3.1",
|
"jest-canvas-mock": "^2.3.1",
|
||||||
|
"jest-environment-jsdom": "^28.1.1",
|
||||||
"jest-fetch-mock": "^3.0.3",
|
"jest-fetch-mock": "^3.0.3",
|
||||||
"jest-mock-extended": "^1.0.18",
|
"jest-mock-extended": "^2.0.6",
|
||||||
"make-plural": "^6.2.2",
|
"make-plural": "^6.2.2",
|
||||||
"mini-css-extract-plugin": "^2.6.0",
|
"mini-css-extract-plugin": "^2.6.0",
|
||||||
"mock-http": "^1.1.0",
|
"mock-http": "^1.1.0",
|
||||||
@ -402,7 +406,6 @@
|
|||||||
"style-loader": "^3.3.1",
|
"style-loader": "^3.3.1",
|
||||||
"tailwindcss": "^3.0.23",
|
"tailwindcss": "^3.0.23",
|
||||||
"tar-stream": "^2.2.0",
|
"tar-stream": "^2.2.0",
|
||||||
"ts-jest": "26.5.6",
|
|
||||||
"ts-loader": "^9.2.8",
|
"ts-loader": "^9.2.8",
|
||||||
"ts-node": "^10.7.0",
|
"ts-node": "^10.7.0",
|
||||||
"type-fest": "^2.13.0",
|
"type-fest": "^2.13.0",
|
||||||
|
|||||||
@ -444,8 +444,14 @@ exports[`helm-charts - navigation to Helm charts when navigating to Helm charts
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Spinner singleColor center"
|
class="NoItems flex box grow"
|
||||||
/>
|
>
|
||||||
|
<div
|
||||||
|
class="box center"
|
||||||
|
>
|
||||||
|
Item list is empty
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="AddRemoveButtons flex gaps"
|
class="AddRemoveButtons flex gaps"
|
||||||
|
|||||||
@ -449,7 +449,7 @@ describe("KubeApi", () => {
|
|||||||
expect(spy).toHaveBeenCalledWith("/api/v1/namespaces/kube-system/pods?watch=1&resourceVersion=", { query: { timeoutSeconds: 60 }}, expect.anything());
|
expect(spy).toHaveBeenCalledWith("/api/v1/namespaces/kube-system/pods?watch=1&resourceVersion=", { query: { timeoutSeconds: 60 }}, expect.anything());
|
||||||
});
|
});
|
||||||
|
|
||||||
it("aborts watch using abortController", async (done) => {
|
it("aborts watch using abortController", (done) => {
|
||||||
const spy = jest.spyOn(request, "getResponse");
|
const spy = jest.spyOn(request, "getResponse");
|
||||||
|
|
||||||
mockFetch.mockResponse(async request => {
|
mockFetch.mockResponse(async request => {
|
||||||
@ -472,10 +472,7 @@ describe("KubeApi", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledWith("/api/v1/namespaces/kube-system/pods?watch=1&resourceVersion=", { query: { timeoutSeconds: 60 }}, expect.anything());
|
expect(spy).toHaveBeenCalledWith("/api/v1/namespaces/kube-system/pods?watch=1&resourceVersion=", { query: { timeoutSeconds: 60 }}, expect.anything());
|
||||||
|
delay(100).then(() => abortController.abort());
|
||||||
await delay(100);
|
|
||||||
|
|
||||||
abortController.abort();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("retries", () => {
|
describe("retries", () => {
|
||||||
|
|||||||
@ -2,4 +2,4 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
export const flushPromises = () => new Promise(setImmediate);
|
export const flushPromises = () => new Promise(resolve => setTimeout(resolve, 0));
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { runInAction } from "mobx";
|
|||||||
import updateExtensionsStateInjectable from "../extension-loader/update-extensions-state/update-extensions-state.injectable";
|
import updateExtensionsStateInjectable from "../extension-loader/update-extensions-state/update-extensions-state.injectable";
|
||||||
import mockFs from "mock-fs";
|
import mockFs from "mock-fs";
|
||||||
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
|
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
|
||||||
|
import { delay } from "../../renderer/utils";
|
||||||
|
|
||||||
console = new Console(stdout, stderr);
|
console = new Console(stdout, stderr);
|
||||||
|
|
||||||
@ -125,42 +126,39 @@ describe("ExtensionLoader", () => {
|
|||||||
mockFs.restore();
|
mockFs.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renderer updates extension after ipc broadcast", async done => {
|
it("renderer updates extension after ipc broadcast", async () => {
|
||||||
expect(extensionLoader.userExtensions).toMatchInlineSnapshot(`Map {}`);
|
expect(extensionLoader.userExtensions).toMatchInlineSnapshot(`Map {}`);
|
||||||
|
|
||||||
await extensionLoader.init();
|
await extensionLoader.init();
|
||||||
|
await delay(10);
|
||||||
|
|
||||||
setTimeout(() => {
|
// Assert the extensions after the extension broadcast event
|
||||||
// Assert the extensions after the extension broadcast event
|
expect(extensionLoader.userExtensions).toMatchInlineSnapshot(`
|
||||||
expect(extensionLoader.userExtensions).toMatchInlineSnapshot(`
|
Map {
|
||||||
Map {
|
"manifest/path" => Object {
|
||||||
"manifest/path" => Object {
|
"absolutePath": "/test/1",
|
||||||
"absolutePath": "/test/1",
|
"id": "manifest/path",
|
||||||
"id": "manifest/path",
|
"isBundled": false,
|
||||||
"isBundled": false,
|
"isEnabled": true,
|
||||||
"isEnabled": true,
|
"manifest": Object {
|
||||||
"manifest": Object {
|
"name": "TestExtension",
|
||||||
"name": "TestExtension",
|
"version": "1.0.0",
|
||||||
"version": "1.0.0",
|
|
||||||
},
|
|
||||||
"manifestPath": "manifest/path",
|
|
||||||
},
|
},
|
||||||
"manifest/path3" => Object {
|
"manifestPath": "manifest/path",
|
||||||
"absolutePath": "/test/3",
|
},
|
||||||
"id": "manifest/path3",
|
"manifest/path3" => Object {
|
||||||
"isBundled": false,
|
"absolutePath": "/test/3",
|
||||||
"isEnabled": true,
|
"id": "manifest/path3",
|
||||||
"manifest": Object {
|
"isBundled": false,
|
||||||
"name": "TestExtension3",
|
"isEnabled": true,
|
||||||
"version": "3.0.0",
|
"manifest": Object {
|
||||||
},
|
"name": "TestExtension3",
|
||||||
"manifestPath": "manifest/path3",
|
"version": "3.0.0",
|
||||||
},
|
},
|
||||||
}
|
"manifestPath": "manifest/path3",
|
||||||
`);
|
},
|
||||||
|
}
|
||||||
done();
|
`);
|
||||||
}, 10);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("updates ExtensionsStore after isEnabled is changed", async () => {
|
it("updates ExtensionsStore after isEnabled is changed", async () => {
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import installExtensionInjectable
|
|||||||
import directoryForUserDataInjectable
|
import directoryForUserDataInjectable
|
||||||
from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
import mockFs from "mock-fs";
|
import mockFs from "mock-fs";
|
||||||
|
import { delay } from "../../renderer/utils";
|
||||||
|
import { observable, when } from "mobx";
|
||||||
|
|
||||||
jest.setTimeout(60_000);
|
jest.setTimeout(60_000);
|
||||||
|
|
||||||
@ -64,7 +66,8 @@ describe("ExtensionDiscovery", () => {
|
|||||||
mockFs.restore();
|
mockFs.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("emits add for added extension", async (done) => {
|
it("emits add for added extension", async () => {
|
||||||
|
const letTestFinish = observable.box(false);
|
||||||
let addHandler!: (filePath: string) => void;
|
let addHandler!: (filePath: string) => void;
|
||||||
|
|
||||||
mockedFse.readJson.mockImplementation((p) => {
|
mockedFse.readJson.mockImplementation((p) => {
|
||||||
@ -114,13 +117,14 @@ describe("ExtensionDiscovery", () => {
|
|||||||
},
|
},
|
||||||
manifestPath: path.normalize("some-directory-for-user-data/node_modules/my-extension/package.json"),
|
manifestPath: path.normalize("some-directory-for-user-data/node_modules/my-extension/package.json"),
|
||||||
});
|
});
|
||||||
done();
|
letTestFinish.set(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
addHandler(path.join(extensionDiscovery.localFolderPath, "/my-extension/package.json"));
|
addHandler(path.join(extensionDiscovery.localFolderPath, "/my-extension/package.json"));
|
||||||
|
await when(() => letTestFinish.get());
|
||||||
});
|
});
|
||||||
|
|
||||||
it("doesn't emit add for added file under extension", async done => {
|
it("doesn't emit add for added file under extension", async () => {
|
||||||
let addHandler!: (filePath: string) => void;
|
let addHandler!: (filePath: string) => void;
|
||||||
|
|
||||||
const mockWatchInstance = {
|
const mockWatchInstance = {
|
||||||
@ -146,10 +150,8 @@ describe("ExtensionDiscovery", () => {
|
|||||||
|
|
||||||
addHandler(path.join(extensionDiscovery.localFolderPath, "/my-extension/node_modules/dep/package.json"));
|
addHandler(path.join(extensionDiscovery.localFolderPath, "/my-extension/node_modules/dep/package.json"));
|
||||||
|
|
||||||
setTimeout(() => {
|
await delay(10);
|
||||||
expect(onAdd).not.toHaveBeenCalled();
|
|
||||||
done();
|
expect(onAdd).not.toHaveBeenCalled();
|
||||||
}, 10);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
32
src/jest-28-resolver.js
Normal file
32
src/jest-28-resolver.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
module.exports = (path, options) => {
|
||||||
|
// Call the defaultResolver, so we leverage its cache, error handling, etc.
|
||||||
|
return options.defaultResolver(path, {
|
||||||
|
...options,
|
||||||
|
// Use packageFilter to process parsed `package.json` before the resolution (see https://www.npmjs.com/package/resolve#resolveid-opts-cb)
|
||||||
|
packageFilter: pkg => {
|
||||||
|
// This is a workaround for https://github.com/uuidjs/uuid/pull/616
|
||||||
|
//
|
||||||
|
// jest-environment-jsdom 28+ tries to use browser exports instead of default exports,
|
||||||
|
// but uuid only offers an ESM browser export and not a CommonJS one. Jest does not yet
|
||||||
|
// support ESM modules natively, so this causes a Jest error related to trying to parse
|
||||||
|
// "export" syntax.
|
||||||
|
//
|
||||||
|
// This workaround prevents Jest from considering uuid's module-based exports at all;
|
||||||
|
// it falls back to uuid's CommonJS+node "main" property.
|
||||||
|
//
|
||||||
|
// Once we're able to migrate our Jest config to ESM and a browser crypto
|
||||||
|
// implementation is available for the browser+ESM version of uuid to use (eg, via
|
||||||
|
// https://github.com/jsdom/jsdom/pull/3352 or a similar polyfill), this can go away.
|
||||||
|
if (pkg.name === "uuid") {
|
||||||
|
delete pkg["exports"];
|
||||||
|
delete pkg["module"];
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkg;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
@ -22,6 +22,8 @@ fetchMock.enableMocks();
|
|||||||
// Mock __non_webpack_require__ for tests
|
// Mock __non_webpack_require__ for tests
|
||||||
globalThis.__non_webpack_require__ = jest.fn();
|
globalThis.__non_webpack_require__ = jest.fn();
|
||||||
|
|
||||||
|
global.setImmediate = jest.useRealTimers as unknown as typeof setImmediate;
|
||||||
|
|
||||||
process.on("unhandledRejection", (err: any) => {
|
process.on("unhandledRejection", (err: any) => {
|
||||||
fail(err);
|
fail(err);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -63,19 +63,11 @@ describe("protocol router tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should throw on non-lens URLS", async () => {
|
it("should throw on non-lens URLS", async () => {
|
||||||
try {
|
expect(lpr.route("https://google.ca")).rejects.toBeDefined();
|
||||||
expect(await lpr.route("https://google.ca")).toBeUndefined();
|
|
||||||
} catch (error) {
|
|
||||||
expect(error).toBeInstanceOf(Error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw when host not internal or extension", async () => {
|
it("should throw when host not internal or extension", async () => {
|
||||||
try {
|
expect(lpr.route("lens://foobar")).rejects.toBeDefined();
|
||||||
expect(await lpr.route("lens://foobar")).toBeUndefined();
|
|
||||||
} catch (error) {
|
|
||||||
expect(error).toBeInstanceOf(Error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not throw when has valid host", async () => {
|
it("should not throw when has valid host", async () => {
|
||||||
|
|||||||
@ -134,7 +134,7 @@ class NonInjectedAddCluster extends React.Component<Dependencies> {
|
|||||||
{this.allErrors.length > 0 && (
|
{this.allErrors.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<h3>KubeConfig Yaml Validation Errors:</h3>
|
<h3>KubeConfig Yaml Validation Errors:</h3>
|
||||||
{...this.allErrors.map(error => <div key={error} className="error">{error}</div>)}
|
{this.allErrors.map(error => <div key={error} className="error">{error}</div>)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="actions-panel">
|
<div className="actions-panel">
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { observable } from "mobx";
|
||||||
|
|
||||||
|
const badgeHasTextSelectedStateInjectable = getInjectable({
|
||||||
|
id: "badge-has-text-selected-state",
|
||||||
|
instantiate: () => observable.box(false),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default badgeHasTextSelectedStateInjectable;
|
||||||
@ -18,6 +18,7 @@ exports[`<Tooltip /> renders to DOM when forced to by visibile prop 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="Tooltip visible"
|
class="Tooltip visible"
|
||||||
role="tooltip"
|
role="tooltip"
|
||||||
|
style="left: 10px; top: 0px;"
|
||||||
>
|
>
|
||||||
I am a tooltip
|
I am a tooltip
|
||||||
</div>
|
</div>
|
||||||
@ -34,7 +35,7 @@ exports[`<Tooltip /> renders to DOM when hovering over target 1`] = `
|
|||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="Tooltip right"
|
class="Tooltip visible"
|
||||||
role="tooltip"
|
role="tooltip"
|
||||||
style="left: 10px; top: 0px;"
|
style="left: 10px; top: 0px;"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -10,6 +10,23 @@ import React from "react";
|
|||||||
import { Tooltip } from "./tooltip";
|
import { Tooltip } from "./tooltip";
|
||||||
|
|
||||||
describe("<Tooltip />", () => {
|
describe("<Tooltip />", () => {
|
||||||
|
let requestAnimationFrameSpy: jest.SpyInstance<number, [callback: FrameRequestCallback]>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
requestAnimationFrameSpy = jest.spyOn(window, "requestAnimationFrame");
|
||||||
|
|
||||||
|
requestAnimationFrameSpy.mockImplementation(cb => {
|
||||||
|
cb(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
requestAnimationFrameSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it("does not render to DOM if not visibile", () => {
|
it("does not render to DOM if not visibile", () => {
|
||||||
const result = render((
|
const result = render((
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -79,6 +79,7 @@ export class Tooltip extends React.Component<TooltipProps> {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.hoverTarget?.addEventListener("mouseenter", this.onEnterTarget);
|
this.hoverTarget?.addEventListener("mouseenter", this.onEnterTarget);
|
||||||
this.hoverTarget?.addEventListener("mouseleave", this.onLeaveTarget);
|
this.hoverTarget?.addEventListener("mouseleave", this.onLeaveTarget);
|
||||||
|
this.refreshPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
@ -110,7 +111,8 @@ export class Tooltip extends React.Component<TooltipProps> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let positions = new Set<TooltipPosition>([
|
const positions = new Set<TooltipPosition>([
|
||||||
|
...[preferredPositions ?? []].flat(),
|
||||||
TooltipPosition.RIGHT,
|
TooltipPosition.RIGHT,
|
||||||
TooltipPosition.BOTTOM,
|
TooltipPosition.BOTTOM,
|
||||||
TooltipPosition.TOP,
|
TooltipPosition.TOP,
|
||||||
@ -121,13 +123,6 @@ export class Tooltip extends React.Component<TooltipProps> {
|
|||||||
TooltipPosition.BOTTOM_LEFT,
|
TooltipPosition.BOTTOM_LEFT,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (preferredPositions) {
|
|
||||||
positions = new Set([
|
|
||||||
...[preferredPositions].flat(),
|
|
||||||
...positions,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset position first and get all possible client-rect area for tooltip element
|
// reset position first and get all possible client-rect area for tooltip element
|
||||||
this.setPosition(elem, { left: 0, top: 0 });
|
this.setPosition(elem, { left: 0, top: 0 });
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user