From 5c766367c530b271441662004fbd47e1a45d55ae Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Mon, 13 Mar 2023 08:27:57 +0200 Subject: [PATCH] Extract startable-stoppable to NPM package Signed-off-by: Janne Savolainen --- .../startable-stoppable/index.ts | 7 ++ .../startable-stoppable/jest.config.js | 2 + .../startable-stoppable/package.json | 29 ++++++++ .../src/get-startable-stoppable.test.ts | 66 +++++++++++++++++++ .../src/get-startable-stoppable.ts | 43 ++++++++++++ .../startable-stoppable/tsconfig.json | 3 + .../startable-stoppable/webpack.config.js | 1 + 7 files changed, 151 insertions(+) create mode 100644 packages/utility-features/startable-stoppable/index.ts create mode 100644 packages/utility-features/startable-stoppable/jest.config.js create mode 100644 packages/utility-features/startable-stoppable/package.json create mode 100644 packages/utility-features/startable-stoppable/src/get-startable-stoppable.test.ts create mode 100644 packages/utility-features/startable-stoppable/src/get-startable-stoppable.ts create mode 100644 packages/utility-features/startable-stoppable/tsconfig.json create mode 100644 packages/utility-features/startable-stoppable/webpack.config.js diff --git a/packages/utility-features/startable-stoppable/index.ts b/packages/utility-features/startable-stoppable/index.ts new file mode 100644 index 0000000000..e5dddee5be --- /dev/null +++ b/packages/utility-features/startable-stoppable/index.ts @@ -0,0 +1,7 @@ +export type { + StartableStoppable, + Starter, + Stopper, +} from "./src/get-startable-stoppable"; + +export { getStartableStoppable } from "./src/get-startable-stoppable"; diff --git a/packages/utility-features/startable-stoppable/jest.config.js b/packages/utility-features/startable-stoppable/jest.config.js new file mode 100644 index 0000000000..23be80353b --- /dev/null +++ b/packages/utility-features/startable-stoppable/jest.config.js @@ -0,0 +1,2 @@ +module.exports = + require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact; diff --git a/packages/utility-features/startable-stoppable/package.json b/packages/utility-features/startable-stoppable/package.json new file mode 100644 index 0000000000..053c849b90 --- /dev/null +++ b/packages/utility-features/startable-stoppable/package.json @@ -0,0 +1,29 @@ +{ + "name": "@k8slens/startable-stoppable", + "private": false, + "version": "6.5.0-alpha.0", + "description": "TBD", + "type": "commonjs", + "files": [ + "build" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/lensapp/lens.git" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "author": { + "name": "OpenLens Authors", + "email": "info@k8slens.dev" + }, + "license": "MIT", + "homepage": "https://github.com/lensapp/lens", + "scripts": { + "build": "webpack", + "dev": "webpack --mode=development --watch", + "test": "jest --coverage --runInBand", + "lint": "lens-lint", + "lint:fix": "lens-lint --fix" + } +} diff --git a/packages/utility-features/startable-stoppable/src/get-startable-stoppable.test.ts b/packages/utility-features/startable-stoppable/src/get-startable-stoppable.test.ts new file mode 100644 index 0000000000..ad9b8c6921 --- /dev/null +++ b/packages/utility-features/startable-stoppable/src/get-startable-stoppable.test.ts @@ -0,0 +1,66 @@ +import type { StartableStoppable } from "./get-startable-stoppable"; +import { getStartableStoppable } from "./get-startable-stoppable"; + +describe("getStartableStoppable", () => { + let stopMock: jest.MockedFunction<() => void>; + let startMock: jest.MockedFunction<() => () => void>; + let actual: StartableStoppable; + + beforeEach(() => { + stopMock = jest.fn(); + startMock = jest.fn().mockImplementation(() => stopMock); + actual = getStartableStoppable("some-id", startMock); + }); + + it("does not start yet", () => { + expect(startMock).not.toHaveBeenCalled(); + }); + + it("does not stop yet", () => { + expect(stopMock).not.toHaveBeenCalled(); + }); + + it("when stopping before ever starting, throws", () => { + expect(() => actual.stop()).toThrow( + 'Tried to stop "some-id", but it is already stopped.' + ); + }); + + it("is not started", () => { + expect(actual.started).toBe(false); + }); + + describe("when started", () => { + beforeEach(() => { + actual.start(); + }); + + it("calls start function", () => { + expect(startMock).toHaveBeenCalled(); + }); + + it("is started", () => { + expect(actual.started).toBe(true); + }); + + it("when started again, throws", () => { + expect(() => actual.start()).toThrow( + 'Tried to start "some-id", but it is already started.' + ); + }); + + describe("when stopped", () => { + beforeEach(() => { + actual.stop(); + }); + + it("calls stop function", () => { + expect(stopMock).toBeCalled(); + }); + + it("is stopped", () => { + expect(actual.started).toBe(false); + }); + }); + }); +}); diff --git a/packages/utility-features/startable-stoppable/src/get-startable-stoppable.ts b/packages/utility-features/startable-stoppable/src/get-startable-stoppable.ts new file mode 100644 index 0000000000..1aac8274a6 --- /dev/null +++ b/packages/utility-features/startable-stoppable/src/get-startable-stoppable.ts @@ -0,0 +1,43 @@ +export type Stopper = () => void; +export type Starter = () => Stopper; + +export interface StartableStoppable { + readonly started: boolean; + start: () => void; + stop: () => void; +} + +type StartableStoppableState = "stopped" | "started" | "starting"; + +export function getStartableStoppable( + id: string, + startAndGetStopper: Starter +): StartableStoppable { + let stop: Stopper; + let state: StartableStoppableState = "stopped"; + + return { + get started() { + return state === "started"; + }, + + start: () => { + if (state !== "stopped") { + throw new Error(`Tried to start "${id}", but it is already ${state}.`); + } + + state = "starting"; + stop = startAndGetStopper(); + state = "started"; + }, + + stop: () => { + if (state !== "started") { + throw new Error(`Tried to stop "${id}", but it is already ${state}.`); + } + + stop(); + state = "stopped"; + }, + }; +} diff --git a/packages/utility-features/startable-stoppable/tsconfig.json b/packages/utility-features/startable-stoppable/tsconfig.json new file mode 100644 index 0000000000..a4f6fa613e --- /dev/null +++ b/packages/utility-features/startable-stoppable/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@k8slens/typescript/config/base.json" +} diff --git a/packages/utility-features/startable-stoppable/webpack.config.js b/packages/utility-features/startable-stoppable/webpack.config.js new file mode 100644 index 0000000000..3183f30179 --- /dev/null +++ b/packages/utility-features/startable-stoppable/webpack.config.js @@ -0,0 +1 @@ +module.exports = require("@k8slens/webpack").configForNode;