From 4ff00e278a80bafa668eef29e0dd9d3c867aead8 Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Sun, 18 Aug 2024 19:52:21 +0200 Subject: [PATCH] Moved path_exists and promises to es6 --- src/node/db/Pad.ts | 9 +++-- src/node/db/SessionManager.ts | 4 +-- src/node/hooks/i18n.ts | 2 +- src/node/server.ts | 8 +++-- src/node/utils/path_exists.ts | 4 +-- src/node/utils/promises.ts | 7 ++-- src/tests/backend-new/specs/path_exists.ts | 22 ++++++++++++ .../specs/promises.ts | 34 +++++++++---------- 8 files changed, 59 insertions(+), 31 deletions(-) create mode 100644 src/tests/backend-new/specs/path_exists.ts rename src/tests/{backend => backend-new}/specs/promises.ts (70%) diff --git a/src/node/db/Pad.ts b/src/node/db/Pad.ts index c3e11aa15..8937fc0eb 100644 --- a/src/node/db/Pad.ts +++ b/src/node/db/Pad.ts @@ -25,7 +25,8 @@ const randomString = require('../utils/randomstring'); const hooks = require('../../static/js/pluginfw/hooks'); import pad_utils from "../../static/js/pad_utils"; import {SmartOpAssembler} from "../../static/js/SmartOpAssembler"; -const promises = require('../utils/promises'); +import {} from '../utils/promises'; +import {timesLimit} from "async"; /** * Copied from the Etherpad source code. It converts Windows line breaks to Unix @@ -586,12 +587,14 @@ class Pad { p.push(db.remove(`pad2readonly:${padID}`)); // delete all chat messages - p.push(promises.timesLimit(this.chatHead + 1, 500, async (i: string) => { + // @ts-ignore + p.push(timesLimit(this.chatHead + 1, 500, async (i: string) => { await this.db.remove(`pad:${this.id}:chat:${i}`, null); })); // delete all revisions - p.push(promises.timesLimit(this.head + 1, 500, async (i: string) => { + // @ts-ignore + p.push(timesLimit(this.head + 1, 500, async (i: string) => { await this.db.remove(`pad:${this.id}:revs:${i}`, null); })); diff --git a/src/node/db/SessionManager.ts b/src/node/db/SessionManager.ts index c0e43a659..2d1327aa6 100644 --- a/src/node/db/SessionManager.ts +++ b/src/node/db/SessionManager.ts @@ -21,7 +21,7 @@ */ const CustomError = require('../utils/customError'); -const promises = require('../utils/promises'); +import {firstSatisfies} from '../utils/promises'; const randomString = require('../utils/randomstring'); const db = require('./DB'); const groupManager = require('./GroupManager'); @@ -79,7 +79,7 @@ exports.findAuthorID = async (groupID:string, sessionCookie: string) => { groupID: string; validUntil: number; }|null) => (si != null && si.groupID === groupID && now < si.validUntil); - const sessionInfo = await promises.firstSatisfies(sessionInfoPromises, isMatch); + const sessionInfo = await firstSatisfies(sessionInfoPromises, isMatch) as any; if (sessionInfo == null) return undefined; return sessionInfo.authorID; }; diff --git a/src/node/hooks/i18n.ts b/src/node/hooks/i18n.ts index c4cc58bdd..69c313d0d 100644 --- a/src/node/hooks/i18n.ts +++ b/src/node/hooks/i18n.ts @@ -8,7 +8,7 @@ const fs = require('fs'); const path = require('path'); const _ = require('underscore'); const pluginDefs = require('../../static/js/pluginfw/plugin_defs'); -const existsSync = require('../utils/path_exists'); +import existsSync from '../utils/path_exists'; const settings = require('../utils/Settings'); // returns all existing messages merged together and grouped by langcode diff --git a/src/node/server.ts b/src/node/server.ts index f96db3ab1..507ed5f79 100755 --- a/src/node/server.ts +++ b/src/node/server.ts @@ -74,7 +74,7 @@ const express = require('./hooks/express'); const hooks = require('../static/js/pluginfw/hooks'); const pluginDefs = require('../static/js/pluginfw/plugin_defs'); const plugins = require('../static/js/pluginfw/plugins'); -const {Gate} = require('./utils/promises'); +import {Gate} from './utils/promises'; const stats = require('./stats') const logger = log4js.getLogger('server'); @@ -100,7 +100,7 @@ const removeSignalListener = (signal: NodeJS.Signals, listener: NodeJS.SignalsLi }; -let startDoneGate: { resolve: () => void; } +let startDoneGate: Gate exports.start = async () => { switch (state) { case State.INITIAL: @@ -181,12 +181,14 @@ exports.start = async () => { } catch (err) { logger.error('Error occurred while starting Etherpad'); state = State.STATE_TRANSITION_FAILED; + // @ts-ignore startDoneGate.resolve(); return await exports.exit(err); } logger.info('Etherpad is running'); state = State.RUNNING; + // @ts-ignore startDoneGate.resolve(); // Return the HTTP server to make it easier to write tests. @@ -228,11 +230,13 @@ exports.stop = async () => { } catch (err) { logger.error('Error occurred while stopping Etherpad'); state = State.STATE_TRANSITION_FAILED; + // @ts-ignore stopDoneGate.resolve(); return await exports.exit(err); } logger.info('Etherpad stopped'); state = State.STOPPED; + // @ts-ignore stopDoneGate.resolve(); }; diff --git a/src/node/utils/path_exists.ts b/src/node/utils/path_exists.ts index 354cd3cc7..cb48f2fa9 100644 --- a/src/node/utils/path_exists.ts +++ b/src/node/utils/path_exists.ts @@ -1,5 +1,5 @@ 'use strict'; -const fs = require('fs'); +import fs from 'node:fs'; const check = (path:string) => { const existsSync = fs.statSync || fs.existsSync; @@ -13,4 +13,4 @@ const check = (path:string) => { return result; }; -module.exports = check; +export default check; diff --git a/src/node/utils/promises.ts b/src/node/utils/promises.ts index 701c5da89..9d07ed00b 100644 --- a/src/node/utils/promises.ts +++ b/src/node/utils/promises.ts @@ -7,7 +7,7 @@ // `predicate`. Resolves to `undefined` if none of the Promises satisfy `predicate`, or if // `promises` is empty. If `predicate` is nullish, the truthiness of the resolved value is used as // the predicate. -exports.firstSatisfies = (promises: Promise[], predicate: null|Function) => { +export const firstSatisfies = (promises: Promise[], predicate: null|Function) => { if (predicate == null) { predicate = (x: any) => x; } @@ -44,7 +44,7 @@ exports.firstSatisfies = (promises: Promise[], predicate: null|Function) = // `total` is greater than `concurrency`, then `concurrency` Promises will be created right away, // and each remaining Promise will be created once one of the earlier Promises resolves.) This async // function resolves once all `total` Promises have resolved. -exports.timesLimit = async (total: number, concurrency: number, promiseCreator: Function) => { +export const timesLimit = async (total: number, concurrency: number, promiseCreator: Function) => { if (total > 0 && concurrency <= 0) throw new RangeError('concurrency must be positive'); let next = 0; const addAnother = () => promiseCreator(next++).finally(() => { @@ -61,7 +61,7 @@ exports.timesLimit = async (total: number, concurrency: number, promiseCreator: * An ordinary Promise except the `resolve` and `reject` executor functions are exposed as * properties. */ -class Gate extends Promise { +export class Gate extends Promise { // Coax `.then()` into returning an ordinary Promise, not a Gate. See // https://stackoverflow.com/a/65669070 for the rationale. static get [Symbol.species]() { return Promise; } @@ -75,4 +75,3 @@ class Gate extends Promise { Object.assign(this, props); } } -exports.Gate = Gate; diff --git a/src/tests/backend-new/specs/path_exists.ts b/src/tests/backend-new/specs/path_exists.ts new file mode 100644 index 000000000..5c719d05e --- /dev/null +++ b/src/tests/backend-new/specs/path_exists.ts @@ -0,0 +1,22 @@ +import check from "../../../node/utils/path_exists"; +import {expect, describe, it} from "vitest"; + +describe('Test path exists', function () { + it('should return true if the path exists - directory', function () { + const path = './locales'; + const result = check(path); + expect(result).toBeTruthy(); + }); + + it('should return true if the path exists - file', function () { + const path = './locales/en.json'; + const result = check(path); + expect(result).toBeTruthy(); + }) + + it('should return false if the path does not exist', function () { + const path = './path_not_exists.ts'; + const result = check(path); + expect(result).toEqual(false); + }); +}) diff --git a/src/tests/backend/specs/promises.ts b/src/tests/backend-new/specs/promises.ts similarity index 70% rename from src/tests/backend/specs/promises.ts rename to src/tests/backend-new/specs/promises.ts index 66be23562..2ce6aed27 100644 --- a/src/tests/backend/specs/promises.ts +++ b/src/tests/backend-new/specs/promises.ts @@ -1,7 +1,7 @@ import {MapArrayType} from "../../../node/types/MapType"; -const assert = require('assert').strict; -const promises = require('../../../node/utils/promises'); +import {timesLimit} from '../../../node/utils/promises'; +import {describe, it, expect} from "vitest"; describe(__filename, function () { describe('promises.timesLimit', function () { @@ -15,7 +15,7 @@ describe(__filename, function () { const testPromises: TestPromise[] = []; const makePromise = (index: number) => { // Make sure index increases by one each time. - assert.equal(index, wantIndex++); + expect(index).toEqual(wantIndex++); // Save the resolve callback (so the test can trigger resolution) // and the promise itself (to wait for resolve to take effect). const p:TestPromise = {}; @@ -28,17 +28,17 @@ describe(__filename, function () { const total = 11; const concurrency = 7; - const timesLimitPromise = promises.timesLimit(total, concurrency, makePromise); + const timesLimitPromise = timesLimit(total, concurrency, makePromise); it('honors concurrency', async function () { - assert.equal(wantIndex, concurrency); + expect(wantIndex).toEqual(concurrency); }); it('creates another when one completes', async function () { const {promise, resolve} = testPromises.shift()!; resolve!(); await promise; - assert.equal(wantIndex, concurrency + 1); + expect(wantIndex).toEqual(concurrency + 1); }); it('creates the expected total number of promises', async function () { @@ -49,7 +49,7 @@ describe(__filename, function () { resolve!(); await promise; } - assert.equal(wantIndex, total); + expect(wantIndex).toEqual(total); }); it('resolves', async function () { @@ -58,35 +58,35 @@ describe(__filename, function () { it('does not create too many promises if total < concurrency', async function () { wantIndex = 0; - assert.equal(testPromises.length, 0); + expect(testPromises.length).toEqual(0); const total = 7; const concurrency = 11; - const timesLimitPromise = promises.timesLimit(total, concurrency, makePromise); + const timesLimitPromise = timesLimit(total, concurrency, makePromise); while (testPromises.length > 0) { const {promise, resolve} = testPromises.pop()!; resolve!(); await promise; } await timesLimitPromise; - assert.equal(wantIndex, total); + expect(wantIndex).toEqual(total); }); it('accepts total === 0, concurrency > 0', async function () { wantIndex = 0; - assert.equal(testPromises.length, 0); - await promises.timesLimit(0, concurrency, makePromise); - assert.equal(wantIndex, 0); + expect(testPromises.length).toEqual(0); + await timesLimit(0, concurrency, makePromise); + expect(wantIndex).toEqual(0); }); it('accepts total === 0, concurrency === 0', async function () { wantIndex = 0; - assert.equal(testPromises.length, 0); - await promises.timesLimit(0, 0, makePromise); - assert.equal(wantIndex, 0); + expect(testPromises.length).toEqual(0); + await timesLimit(0, 0, makePromise); + expect(wantIndex).toEqual(0); }); it('rejects total > 0, concurrency === 0', async function () { - await assert.rejects(promises.timesLimit(total, 0, makePromise), RangeError); + expect(timesLimit(total, 0, makePromise)).rejects.toThrow(RangeError); }); }); });