1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Introduce reactive now to kludge around global shared state in library

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
Janne Savolainen 2022-07-01 09:58:05 +03:00
parent c11ac4e2bc
commit 9e5f0b468b
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
2 changed files with 130 additions and 0 deletions

View File

@ -0,0 +1,70 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { RenderResult } from "@testing-library/react";
import { render } from "@testing-library/react";
import type { IComputedValue } from "mobx";
import { computed, observe } from "mobx";
import React from "react";
import { observer } from "mobx-react";
import { advanceFakeTime, useFakeTime } from "../../test-utils/use-fake-time";
import { reactiveNow } from "./reactive-now";
describe("reactiveNow", () => {
let someComputed: IComputedValue<boolean>;
beforeEach(() => {
useFakeTime("2015-10-21T07:28:00Z");
someComputed = computed(() => {
const currentTimestamp = reactiveNow();
return currentTimestamp > new Date("2015-10-21T07:28:00Z").getTime();
});
});
describe("react-context", () => {
let rendered: RenderResult;
beforeEach(() => {
const TestComponent = observer(
({ someComputed }: { someComputed: IComputedValue<boolean> }) => (
<div>{someComputed.get() ? "true" : "false"}</div>
),
);
rendered = render(<TestComponent someComputed={someComputed} />);
});
it("given time passes, works", () => {
advanceFakeTime(1000);
expect(rendered.container.textContent).toBe("true");
});
it("does not share the state from previous test", () => {
expect(rendered.container.textContent).toBe("false");
});
});
describe("non-react-context", () => {
let actual: boolean;
beforeEach(() => {
observe(someComputed, (changed) => {
actual = changed.newValue as boolean;
}, true);
});
it("given time passes, works", () => {
advanceFakeTime(1000);
expect(actual).toBe(true);
});
it("does not share the state from previous test", () => {
expect(actual).toBe(false);
});
});
});

View File

@ -0,0 +1,60 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { _isComputingDerivation } from "mobx";
import type { IResource } from "mobx-utils";
import { fromResource } from "mobx-utils";
// Note: This file is copy-pasted from mobx-utils to fix very specific issue.
// TODO: Remove this file once https://github.com/mobxjs/mobx-utils/issues/306 is fixed.
const tickers: Record<number|string, IResource<number>> = {};
export function reactiveNow(interval?: number | "frame") {
if (interval === void 0) { interval = 1000; }
if (!_isComputingDerivation()) {
// See #40
return Date.now();
}
// Note: This is the kludge until https://github.com/mobxjs/mobx-utils/issues/306 is fixed
const synchronizationIsEnabled = !process.env.JEST_WORKER_ID;
if (!tickers[interval] || !synchronizationIsEnabled) {
if (typeof interval === "number")
tickers[interval] = createIntervalTicker(interval);
else
tickers[interval] = createAnimationFrameTicker();
}
return tickers[interval].current();
}
function createIntervalTicker(interval: number) {
let subscriptionHandle: NodeJS.Timer;
return fromResource(function (sink) {
sink(Date.now());
subscriptionHandle = setInterval(function () { return sink(Date.now()); }, interval);
}, function () {
clearInterval(subscriptionHandle);
}, Date.now());
}
function createAnimationFrameTicker() {
const frameBasedTicker = fromResource(function (sink) {
sink(Date.now());
function scheduleTick() {
window.requestAnimationFrame(function () {
sink(Date.now());
if (frameBasedTicker.isAlive())
scheduleTick();
});
}
scheduleTick();
}, function () { }, Date.now());
return frameBasedTicker;
}