From 7e3bc7b45739b2c3888f342384152e748eb172b0 Mon Sep 17 00:00:00 2001 From: kz2d Date: Mon, 22 Aug 2022 12:19:52 +0300 Subject: [PATCH 01/20] added reporter --- package.json | 2 +- src/core/data/spec.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 008907f09..798d9460f 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "test:typescript": "node node_modules/@v4fire/typescript-check", "test:eslint": "eslint config build src", "test:jest": "cross-env NODE_ENV=development && jest", - "test:ci:jest": "cross-env NODE_ENV=development && jest --maxWorkers 4", + "test:ci:jest": "cross-env NODE_ENV=development && jest --maxWorkers 4 --reporters github-actions", "up": "npm i && gulp build:standalone && gulp build:doc" }, "dependencies": { diff --git a/src/core/data/spec.js b/src/core/data/spec.js index 5ad2106e8..67ed2c0bf 100644 --- a/src/core/data/spec.js +++ b/src/core/data/spec.js @@ -47,6 +47,8 @@ describe('core/data', () => { expect(await dp.add({id: 12345, value: 'abc-def-ghi'}).data) .toEqual({message: 'Success'}); + + expect(true).toBe(false); }); it('provider with overrides', async () => { From 29f4432e43bd067aa04d253ee4d73f6c937b79b2 Mon Sep 17 00:00:00 2001 From: kz2d Date: Mon, 22 Aug 2022 12:43:04 +0300 Subject: [PATCH 02/20] added reporter --- .github/workflows/test.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8bc0c051a..de89a33db 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,9 +29,6 @@ jobs: - name: Build tsconfig run: npx gulp build:tsconfig - - name: Run tests - run: npm run test:linters - tests: runs-on: ubuntu-latest From b14f631c1620beece8b97630da7fb3a9c0979f8c Mon Sep 17 00:00:00 2001 From: kz2d Date: Mon, 22 Aug 2022 12:50:21 +0300 Subject: [PATCH 03/20] added reporter --- .github/workflows/test.yml | 3 + jest.config.ts | 8 +- package-lock.json | 121 ++++++++++++++++++++++++++++- package.json | 3 +- src/core/data/spec.js | 1 - src/core/uuid/{spec.js => spec.ts} | 0 6 files changed, 131 insertions(+), 5 deletions(-) rename src/core/uuid/{spec.js => spec.ts} (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index de89a33db..8bc0c051a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,6 +29,9 @@ jobs: - name: Build tsconfig run: npx gulp build:tsconfig + - name: Run tests + run: npm run test:linters + tests: runs-on: ubuntu-latest diff --git a/jest.config.ts b/jest.config.ts index edfc59702..cd3b31f7d 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -13,7 +13,7 @@ export default { projects: [''], - testMatch: ['/dist/server/**/*[sS]pec.js', '/src/**/*[sS]pec.ts'], + testMatch: ['/dist/server/**/*[sS]pec.js'],// '/src/**/*[sS]pec.ts'], rootDir: './', testTimeout: 20000, testEnvironment: 'node', @@ -26,5 +26,9 @@ export default { collectCoverage: true, coverageReporters: ['lcov'], coverageDirectory: '/coverage', - coverageProvider: 'v8' + coverageProvider: 'v8', + + transform: { + '.+\\.ts$': 'ts-jest' + } }; diff --git a/package-lock.json b/package-lock.json index 2fc07d733..a46c02653 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,13 +25,14 @@ "w3c-xmlserializer": "2.0.0" }, "devDependencies": { - "@types/jest": "28.1.4", + "@types/jest": "^28.1.4", "@v4fire/linters": "1.9.0", "abort-controller": "3.0.0", "express": "4.17.3", "husky": "7.0.4", "jest": "28.1.3", "node-fetch": "2.6.2", + "ts-jest": "^28.0.8", "xhr2": "0.2.1" }, "engines": { @@ -5330,6 +5331,18 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -13099,6 +13112,12 @@ "lodash.isarray": "^3.0.0" } }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -17114,6 +17133,64 @@ "node": ">=12" } }, + "node_modules/ts-jest": { + "version": "28.0.8", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", + "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^28.0.0", + "json5": "^2.2.1", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^28.0.0", + "babel-jest": "^28.0.0", + "jest": "^28.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ts-node": { "version": "10.7.0", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", @@ -22220,6 +22297,15 @@ "picocolors": "^1.0.0" } }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, "bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -28290,6 +28376,12 @@ "lodash.isarray": "^3.0.0" } }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -31460,6 +31552,33 @@ "punycode": "^2.1.1" } }, + "ts-jest": { + "version": "28.0.8", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", + "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^28.0.0", + "json5": "^2.2.1", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "ts-node": { "version": "10.7.0", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", diff --git a/package.json b/package.json index 798d9460f..9cea5e1a7 100644 --- a/package.json +++ b/package.json @@ -100,13 +100,14 @@ "upath": "2.0.1" }, "devDependencies": { - "@types/jest": "28.1.4", + "@types/jest": "^28.1.4", "@v4fire/linters": "1.9.0", "abort-controller": "3.0.0", "express": "4.17.3", "husky": "7.0.4", "jest": "28.1.3", "node-fetch": "2.6.2", + "ts-jest": "^28.0.8", "xhr2": "0.2.1" }, "directories": { diff --git a/src/core/data/spec.js b/src/core/data/spec.js index 67ed2c0bf..7bfc2bed2 100644 --- a/src/core/data/spec.js +++ b/src/core/data/spec.js @@ -47,7 +47,6 @@ describe('core/data', () => { expect(await dp.add({id: 12345, value: 'abc-def-ghi'}).data) .toEqual({message: 'Success'}); - expect(true).toBe(false); }); diff --git a/src/core/uuid/spec.js b/src/core/uuid/spec.ts similarity index 100% rename from src/core/uuid/spec.js rename to src/core/uuid/spec.ts From 7d5ba880fb49a01b8ae33ff2405a35053e782de9 Mon Sep 17 00:00:00 2001 From: kz2d Date: Mon, 22 Aug 2022 17:24:22 +0300 Subject: [PATCH 04/20] boom: added ts support --- jest.config.ts | 14 +++++--------- src/test.ts | 9 +++++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/jest.config.ts b/jest.config.ts index cd3b31f7d..7ceb10f3d 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -6,14 +6,10 @@ * https://github.com/V4Fire/Core/blob/master/LICENSE */ -/* - * For a detailed explanation regarding each configuration property and type check, visit: - * https://jestjs.io/docs/configuration - */ - +/** @type {import('ts-jest').InitialOptionsTsJest} */ export default { projects: [''], - testMatch: ['/dist/server/**/*[sS]pec.js'],// '/src/**/*[sS]pec.ts'], + testMatch: ['/dist/server/**/*[sS]pec.js', '/src/**/*[sS]pec.ts'], rootDir: './', testTimeout: 20000, testEnvironment: 'node', @@ -28,7 +24,7 @@ export default { coverageDirectory: '/coverage', coverageProvider: 'v8', - transform: { - '.+\\.ts$': 'ts-jest' - } + preset: 'ts-jest', + modulePaths: ['/src/'], + setupFilesAfterEnv: ['/src/test.ts'] }; diff --git a/src/test.ts b/src/test.ts index e69de29bb..cb4a1f383 100644 --- a/src/test.ts +++ b/src/test.ts @@ -0,0 +1,9 @@ +/*! + * V4Fire Core + * https://github.com/V4Fire/Core + * + * Released under the MIT license + * https://github.com/V4Fire/Core/blob/master/LICENSE + */ + +import 'core/prelude'; From 264ed99e2285b520cf0df45b40ef0aebaa483707 Mon Sep 17 00:00:00 2001 From: kz2d Date: Mon, 22 Aug 2022 17:38:01 +0300 Subject: [PATCH 05/20] boom: added ts support --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9cea5e1a7..89514e59d 100644 --- a/package.json +++ b/package.json @@ -100,14 +100,14 @@ "upath": "2.0.1" }, "devDependencies": { - "@types/jest": "^28.1.4", + "@types/jest": "28.1.4", "@v4fire/linters": "1.9.0", "abort-controller": "3.0.0", "express": "4.17.3", "husky": "7.0.4", "jest": "28.1.3", "node-fetch": "2.6.2", - "ts-jest": "^28.0.8", + "ts-jest": "28.0.8", "xhr2": "0.2.1" }, "directories": { From 6d7279b16ce2bd365be957634bf9a33fd99211cb Mon Sep 17 00:00:00 2001 From: kz2d Date: Tue, 23 Aug 2022 12:30:44 +0300 Subject: [PATCH 06/20] feat: removed test for github-actions --- src/core/data/spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/data/spec.js b/src/core/data/spec.js index 7bfc2bed2..5ad2106e8 100644 --- a/src/core/data/spec.js +++ b/src/core/data/spec.js @@ -47,7 +47,6 @@ describe('core/data', () => { expect(await dp.add({id: 12345, value: 'abc-def-ghi'}).data) .toEqual({message: 'Success'}); - expect(true).toBe(false); }); it('provider with overrides', async () => { From f80366f119037b7fed3e07bfb133dd05a2cc37d6 Mon Sep 17 00:00:00 2001 From: kz2d Date: Tue, 23 Aug 2022 15:15:02 +0300 Subject: [PATCH 07/20] test github-actions --- src/core/uuid/spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/uuid/spec.ts b/src/core/uuid/spec.ts index 281ea6552..7a61d089c 100644 --- a/src/core/uuid/spec.ts +++ b/src/core/uuid/spec.ts @@ -14,6 +14,7 @@ describe('core/uuid', () => { it('`generate`', () => { expect(generate()).toBeInstanceOf(Uint8Array); + expect(true).toBe(false); }); it('`serialize`', () => { From 4b511daf31e3982a40120f3241a7183d997e69f7 Mon Sep 17 00:00:00 2001 From: kz2d Date: Tue, 23 Aug 2022 15:23:04 +0300 Subject: [PATCH 08/20] fix test --- src/core/uuid/spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/uuid/spec.ts b/src/core/uuid/spec.ts index 7a61d089c..281ea6552 100644 --- a/src/core/uuid/spec.ts +++ b/src/core/uuid/spec.ts @@ -14,7 +14,6 @@ describe('core/uuid', () => { it('`generate`', () => { expect(generate()).toBeInstanceOf(Uint8Array); - expect(true).toBe(false); }); it('`serialize`', () => { From 7cb63f721e00a68055bdaf8b1337abe6c0d1bedd Mon Sep 17 00:00:00 2001 From: kz2d Date: Tue, 11 Oct 2022 13:52:51 +0300 Subject: [PATCH 09/20] first try --- index.d.ts | 23 +- package-lock.json | 145 ++++++++++++- package.json | 1 + src/core/error/{spec.js => spec.ts} | 0 src/core/event/{spec.js => spec.ts} | 2 +- src/core/prelude/array/{spec.js => spec.ts} | 0 .../prelude/date/compare/{spec.js => spec.ts} | 0 .../prelude/date/modify/{spec.js => spec.ts} | 0 .../date/relative/{spec.js => spec.ts} | 2 +- .../function/compose/{spec.js => spec.ts} | 0 .../function/curry/{spec.js => spec.ts} | 0 .../function/lazy/{spec.js => spec.ts} | 0 .../function/memoize/{spec.js => spec.ts} | 0 .../number/converters/{spec.js => spec.ts} | 0 .../number/format/{spec.js => spec.ts} | 0 .../number/metrics/{spec.js => spec.ts} | 0 .../number/rounding/{spec.js => spec.ts} | 0 .../prelude/object/clone/{spec.js => spec.ts} | 4 +- .../object/compare/{spec.js => spec.ts} | 0 .../object/convert/{spec.js => spec.ts} | 4 +- .../object/create/{spec.js => spec.ts} | 6 +- .../object/metrics/{spec.js => spec.ts} | 0 .../prelude/object/mixin/{spec.js => spec.ts} | 8 +- .../object/property/{spec.js => spec.ts} | 2 +- src/core/prelude/regexp/{spec.js => spec.ts} | 0 src/core/prelude/string/{spec.js => spec.ts} | 0 .../sync-promise/{spec.js => spec.ts} | 16 +- src/core/prelude/types/{spec.js => spec.ts} | 10 +- .../promise/abortable/{spec.js => spec.ts} | 16 +- src/core/promise/{spec.js => spec.ts} | 2 +- src/core/promise/sync/{spec.js => spec.ts} | 0 src/core/queue/merge/{spec.js => spec.ts} | 2 +- src/core/queue/order/{spec.js => spec.ts} | 14 +- src/core/queue/simple/{spec.js => spec.ts} | 2 +- src/core/queue/worker/interface.ts | 2 +- .../queue/worker/merge/{spec.js => spec.ts} | 58 +++--- .../queue/worker/simple/{spec.js => spec.ts} | 51 +++-- src/core/range/index.ts | 6 +- src/core/range/interface.ts | 3 + src/core/range/{spec.js => spec.ts} | 10 +- .../engines/provider/{spec.js => spec.ts} | 46 ++-- src/core/request/headers/{spec.js => spec.ts} | 0 src/core/request/interface.ts | 8 +- .../stream-buffer/{spec.js => spec.ts} | 8 +- src/core/request/{spec.js => spec.ts} | 197 +++++++++++------- src/core/semver/{spec.js => spec.ts} | 0 src/core/symbol/{spec.js => spec.ts} | 0 src/core/url/{spec.js => spec.ts} | 0 src/core/xml/{spec.js => spec.ts} | 4 +- 49 files changed, 437 insertions(+), 215 deletions(-) rename src/core/error/{spec.js => spec.ts} (100%) rename src/core/event/{spec.js => spec.ts} (96%) rename src/core/prelude/array/{spec.js => spec.ts} (100%) rename src/core/prelude/date/compare/{spec.js => spec.ts} (100%) rename src/core/prelude/date/modify/{spec.js => spec.ts} (100%) rename src/core/prelude/date/relative/{spec.js => spec.ts} (98%) rename src/core/prelude/function/compose/{spec.js => spec.ts} (100%) rename src/core/prelude/function/curry/{spec.js => spec.ts} (100%) rename src/core/prelude/function/lazy/{spec.js => spec.ts} (100%) rename src/core/prelude/function/memoize/{spec.js => spec.ts} (100%) rename src/core/prelude/number/converters/{spec.js => spec.ts} (100%) rename src/core/prelude/number/format/{spec.js => spec.ts} (100%) rename src/core/prelude/number/metrics/{spec.js => spec.ts} (100%) rename src/core/prelude/number/rounding/{spec.js => spec.ts} (100%) rename src/core/prelude/object/clone/{spec.js => spec.ts} (96%) rename src/core/prelude/object/compare/{spec.js => spec.ts} (100%) rename src/core/prelude/object/convert/{spec.js => spec.ts} (98%) rename src/core/prelude/object/create/{spec.js => spec.ts} (95%) rename src/core/prelude/object/metrics/{spec.js => spec.ts} (100%) rename src/core/prelude/object/mixin/{spec.js => spec.ts} (98%) rename src/core/prelude/object/property/{spec.js => spec.ts} (99%) rename src/core/prelude/regexp/{spec.js => spec.ts} (100%) rename src/core/prelude/string/{spec.js => spec.ts} (100%) rename src/core/prelude/structures/sync-promise/{spec.js => spec.ts} (93%) rename src/core/prelude/types/{spec.js => spec.ts} (97%) rename src/core/promise/abortable/{spec.js => spec.ts} (94%) rename src/core/promise/{spec.js => spec.ts} (98%) rename src/core/promise/sync/{spec.js => spec.ts} (100%) rename src/core/queue/merge/{spec.js => spec.ts} (96%) rename src/core/queue/order/{spec.js => spec.ts} (83%) rename src/core/queue/simple/{spec.js => spec.ts} (97%) rename src/core/queue/worker/merge/{spec.js => spec.ts} (66%) rename src/core/queue/worker/simple/{spec.js => spec.ts} (69%) rename src/core/range/{spec.js => spec.ts} (95%) rename src/core/request/engines/provider/{spec.js => spec.ts} (77%) rename src/core/request/headers/{spec.js => spec.ts} (100%) rename src/core/request/modules/stream-buffer/{spec.js => spec.ts} (95%) rename src/core/request/{spec.js => spec.ts} (79%) rename src/core/semver/{spec.js => spec.ts} (100%) rename src/core/symbol/{spec.js => spec.ts} (100%) rename src/core/url/{spec.js => spec.ts} (100%) rename src/core/xml/{spec.js => spec.ts} (91%) diff --git a/index.d.ts b/index.d.ts index 563e21cfa..7191c35c0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2775,7 +2775,8 @@ interface Number { ceil(precision?: number): number; } -type RegExpFlag = '' | 'g' | 'i' | 'm' | 'u' | 'y' | 's'; +type RegExpSingleFlag = '' | 'g' | 'i' | 'm' | 'u' | 'y' | 's'; +type RegExpFlag = `${RegExpSingleFlag}${RegExpSingleFlag}${RegExpSingleFlag}${RegExpSingleFlag}${RegExpSingleFlag}`; interface RegExp { /** @@ -2831,7 +2832,7 @@ interface RegExpConstructor { * @param rgxp * @param flags */ - addFlags(rgxp: RegExp, ...flags: RegExpFlag[]): RegExp; + addFlags(rgxp: RegExp, ...flags: [RegExpFlag, ...RegExpFlag[]]): RegExp; /** * Returns a curried version of `RegExp.addFlags` @@ -2851,7 +2852,7 @@ interface RegExpConstructor { * @param rgxp * @param flags */ - removeFlags(rgxp: RegExp, ...flags: RegExpFlag[]): RegExp; + removeFlags(rgxp: RegExp, ...flags: [RegExpFlag, ...RegExpFlag[]]): RegExp; /** * Returns a curried version of `RegExp.removeFlags` @@ -2871,7 +2872,7 @@ interface RegExpConstructor { * @param rgxp * @param flags */ - setFlags(rgxp: RegExp, ...flags: RegExpFlag[]): RegExp; + setFlags(rgxp: RegExp, ...flags: [RegExpFlag, ...RegExpFlag[]]): RegExp; /** * Returns a curried version of `RegExp.setFlags` @@ -3033,6 +3034,20 @@ interface DateConstructor { */ isBetween(date: Date, left: DateCreateValue, right: DateCreateValue, margin?: number): boolean; + /** + * Returns true if the date is less than the now date + * + * @param date - date that will be checked + */ + isPast(date: Date): boolean; + + /** + * Returns true if the date is greater than the now date + * + * @param date - date that will be checked + */ + isFuture(date: Date): boolean; + /** * Returns a new date based on the current so that it starts at the beginning of a day * @param date diff --git a/package-lock.json b/package-lock.json index a46c02653..83dceb366 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,14 +25,15 @@ "w3c-xmlserializer": "2.0.0" }, "devDependencies": { - "@types/jest": "^28.1.4", + "@types/express": "4.17.14", + "@types/jest": "28.1.4", "@v4fire/linters": "1.9.0", "abort-controller": "3.0.0", "express": "4.17.3", "husky": "7.0.4", "jest": "28.1.3", "node-fetch": "2.6.2", - "ts-jest": "^28.0.8", + "ts-jest": "28.0.8", "xhr2": "0.2.1" }, "engines": { @@ -3705,6 +3706,16 @@ "integrity": "sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==", "optional": true }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, "node_modules/@types/cacheable-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", @@ -3716,12 +3727,44 @@ "@types/responselike": "*" } }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/expect": { "version": "1.20.4", "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", "optional": true }, + "node_modules/@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "node_modules/@types/fs-extra": { "version": "4.0.12", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.12.tgz", @@ -3872,6 +3915,12 @@ "@types/node": "*" } }, + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "dev": true + }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -3895,6 +3944,18 @@ "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", "dev": true }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -3909,6 +3970,16 @@ "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", "dev": true }, + "node_modules/@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dev": true, + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -21023,6 +21094,16 @@ "integrity": "sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==", "optional": true }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, "@types/cacheable-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", @@ -21034,12 +21115,44 @@ "@types/responselike": "*" } }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/expect": { "version": "1.20.4", "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", "optional": true }, + "@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/fs-extra": { "version": "4.0.12", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.12.tgz", @@ -21189,6 +21302,12 @@ "@types/node": "*" } }, + "@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "dev": true + }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -21212,6 +21331,18 @@ "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", "dev": true }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -21226,6 +21357,16 @@ "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", "dev": true }, + "@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dev": true, + "requires": { + "@types/mime": "*", + "@types/node": "*" + } + }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", diff --git a/package.json b/package.json index 89514e59d..8ddddcf7b 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,7 @@ "@v4fire/linters": "1.9.0", "abort-controller": "3.0.0", "express": "4.17.3", + "@types/express": "4.17.14", "husky": "7.0.4", "jest": "28.1.3", "node-fetch": "2.6.2", diff --git a/src/core/error/spec.js b/src/core/error/spec.ts similarity index 100% rename from src/core/error/spec.js rename to src/core/error/spec.ts diff --git a/src/core/event/spec.js b/src/core/event/spec.ts similarity index 96% rename from src/core/event/spec.js rename to src/core/event/spec.ts index 904e68809..dd1c3125e 100644 --- a/src/core/event/spec.js +++ b/src/core/event/spec.ts @@ -18,7 +18,7 @@ describe('core/event', () => { let i = 0; - promise.then(() => { + void promise.then(() => { expect(i).toBe(2); done(); }); diff --git a/src/core/prelude/array/spec.js b/src/core/prelude/array/spec.ts similarity index 100% rename from src/core/prelude/array/spec.js rename to src/core/prelude/array/spec.ts diff --git a/src/core/prelude/date/compare/spec.js b/src/core/prelude/date/compare/spec.ts similarity index 100% rename from src/core/prelude/date/compare/spec.js rename to src/core/prelude/date/compare/spec.ts diff --git a/src/core/prelude/date/modify/spec.js b/src/core/prelude/date/modify/spec.ts similarity index 100% rename from src/core/prelude/date/modify/spec.js rename to src/core/prelude/date/modify/spec.ts diff --git a/src/core/prelude/date/relative/spec.js b/src/core/prelude/date/relative/spec.ts similarity index 98% rename from src/core/prelude/date/relative/spec.js rename to src/core/prelude/date/relative/spec.ts index 2d76a444b..59d457f35 100644 --- a/src/core/prelude/date/relative/spec.js +++ b/src/core/prelude/date/relative/spec.ts @@ -159,7 +159,7 @@ describe('core/prelude/date/relative', () => { { const dateNow = new Date(), - res = new Date(dateNow - (2).weeks()).relativeTo(dateNow); + res = new Date(dateNow.valueOf() - (2).weeks()).relativeTo(dateNow); expect(Object.reject(res, 'diff')).toEqual({ type: 'weeks', diff --git a/src/core/prelude/function/compose/spec.js b/src/core/prelude/function/compose/spec.ts similarity index 100% rename from src/core/prelude/function/compose/spec.js rename to src/core/prelude/function/compose/spec.ts diff --git a/src/core/prelude/function/curry/spec.js b/src/core/prelude/function/curry/spec.ts similarity index 100% rename from src/core/prelude/function/curry/spec.js rename to src/core/prelude/function/curry/spec.ts diff --git a/src/core/prelude/function/lazy/spec.js b/src/core/prelude/function/lazy/spec.ts similarity index 100% rename from src/core/prelude/function/lazy/spec.js rename to src/core/prelude/function/lazy/spec.ts diff --git a/src/core/prelude/function/memoize/spec.js b/src/core/prelude/function/memoize/spec.ts similarity index 100% rename from src/core/prelude/function/memoize/spec.js rename to src/core/prelude/function/memoize/spec.ts diff --git a/src/core/prelude/number/converters/spec.js b/src/core/prelude/number/converters/spec.ts similarity index 100% rename from src/core/prelude/number/converters/spec.js rename to src/core/prelude/number/converters/spec.ts diff --git a/src/core/prelude/number/format/spec.js b/src/core/prelude/number/format/spec.ts similarity index 100% rename from src/core/prelude/number/format/spec.js rename to src/core/prelude/number/format/spec.ts diff --git a/src/core/prelude/number/metrics/spec.js b/src/core/prelude/number/metrics/spec.ts similarity index 100% rename from src/core/prelude/number/metrics/spec.js rename to src/core/prelude/number/metrics/spec.ts diff --git a/src/core/prelude/number/rounding/spec.js b/src/core/prelude/number/rounding/spec.ts similarity index 100% rename from src/core/prelude/number/rounding/spec.js rename to src/core/prelude/number/rounding/spec.ts diff --git a/src/core/prelude/object/clone/spec.js b/src/core/prelude/object/clone/spec.ts similarity index 96% rename from src/core/prelude/object/clone/spec.js rename to src/core/prelude/object/clone/spec.ts index 7932626e8..5e5d22b4c 100644 --- a/src/core/prelude/object/clone/spec.js +++ b/src/core/prelude/object/clone/spec.ts @@ -48,7 +48,7 @@ describe('core/prelude/object/clone/fastClone', () => { }); it('cloning of objects with cycle links', () => { - const obj = {a: 1}; + const obj: Dictionary = {a: 1}; obj.obj = obj; expect(Object.fastClone(obj)).not.toBe(obj); @@ -96,7 +96,7 @@ describe('core/prelude/object/clone/fastClone', () => { }); it('cloning of map objects', () => { - const obj = new Map([[1, 2], [2, {a: 1}]]); + const obj = new Map([[1, 2], [2, {a: 1}]]); expect(Object.fastClone(obj)).not.toBe(obj); expect(Object.fastClone(obj)).toEqual(obj); }); diff --git a/src/core/prelude/object/compare/spec.js b/src/core/prelude/object/compare/spec.ts similarity index 100% rename from src/core/prelude/object/compare/spec.js rename to src/core/prelude/object/compare/spec.ts diff --git a/src/core/prelude/object/convert/spec.js b/src/core/prelude/object/convert/spec.ts similarity index 98% rename from src/core/prelude/object/convert/spec.js rename to src/core/prelude/object/convert/spec.ts index d932cf5cb..ea1f907c0 100644 --- a/src/core/prelude/object/convert/spec.js +++ b/src/core/prelude/object/convert/spec.ts @@ -36,7 +36,7 @@ describe('core/prelude/object/convert', () => { it('serializing of an object with the predefined `toJSON`', () => { const set = new Set([1, 2, 3]); - set.toJSON = () => [...set]; + set['toJSON'] = () => [...set]; expect(Object.trySerialize(set)).toBe('[1,2,3]'); }); @@ -74,7 +74,7 @@ describe('core/prelude/object/convert', () => { it('serializing with an exception', () => { const arr = [1, 2, 3]; - arr.toJSON = () => { + arr['toJSON'] = () => { throw new Error('Boom!'); }; diff --git a/src/core/prelude/object/create/spec.js b/src/core/prelude/object/create/spec.ts similarity index 95% rename from src/core/prelude/object/create/spec.js rename to src/core/prelude/object/create/spec.ts index c17203695..cdad5518c 100644 --- a/src/core/prelude/object/create/spec.js +++ b/src/core/prelude/object/create/spec.ts @@ -72,13 +72,13 @@ describe('core/prelude/object/create', () => { { const dict = Object.select({a: 1, b: 2, c: 3}, ['a', 'b']); expect(dict).toEqual({a: 1, b: 2}); - expect(dict.__proto__).toBe(Object.prototype); + expect((dict).__proto__).toBe(Object.prototype); } { const dict = Object.select({a: 1, b: 2, c: 3, __proto__: null}, ['a', 'b']); expect(dict).toEqual({a: 1, b: 2}); - expect(dict.__proto__).toBeFalsy(); + expect((dict).__proto__).toBeFalsy(); } { @@ -122,7 +122,7 @@ describe('core/prelude/object/create', () => { { const dict = Object.reject({a: 1, b: 2, c: 3}, ['a', 'b']); expect(dict).toEqual({c: 3}); - expect(dict.__proto__).toBe(Object.prototype); + expect((dict).__proto__).toBe(Object.prototype); } { diff --git a/src/core/prelude/object/metrics/spec.js b/src/core/prelude/object/metrics/spec.ts similarity index 100% rename from src/core/prelude/object/metrics/spec.js rename to src/core/prelude/object/metrics/spec.ts diff --git a/src/core/prelude/object/mixin/spec.js b/src/core/prelude/object/mixin/spec.ts similarity index 98% rename from src/core/prelude/object/mixin/spec.js rename to src/core/prelude/object/mixin/spec.ts index 7daeeb1f8..1c9923e68 100644 --- a/src/core/prelude/object/mixin/spec.js +++ b/src/core/prelude/object/mixin/spec.ts @@ -210,13 +210,13 @@ describe('core/prelude/object/mixin', () => { return this._a; }, - set a(value) { + set a(value: number) { this._a = value; } }; const - clone = Object.mixin({withDescriptors: 'onlyAccessors'}, undefined, base); + clone = Object.mixin({withDescriptors: 'onlyAccessors'}, undefined, base); expect(clone).not.toBe(base); expect(clone._a).toBe(1); @@ -233,13 +233,13 @@ describe('core/prelude/object/mixin', () => { return this._a; }, - set a(value) { + set a(value: number) { this._a = value; } }; const - clone = Object.mixin({withAccessors: true}, undefined, base); + clone = Object.mixin({withAccessors: true}, undefined, base); expect(clone).not.toBe(base); expect(clone._a).toBe(1); diff --git a/src/core/prelude/object/property/spec.js b/src/core/prelude/object/property/spec.ts similarity index 99% rename from src/core/prelude/object/property/spec.js rename to src/core/prelude/object/property/spec.ts index 098928066..6e899dfed 100644 --- a/src/core/prelude/object/property/spec.js +++ b/src/core/prelude/object/property/spec.ts @@ -133,7 +133,7 @@ describe('core/prelude/object/property/set', () => { expect( Object.set(obj, 'a', 2, { - setter(obj, key, value) { + setter(obj: Dictionary, key: string, value: number) { obj[key] = value * 2; } }) diff --git a/src/core/prelude/regexp/spec.js b/src/core/prelude/regexp/spec.ts similarity index 100% rename from src/core/prelude/regexp/spec.js rename to src/core/prelude/regexp/spec.ts diff --git a/src/core/prelude/string/spec.js b/src/core/prelude/string/spec.ts similarity index 100% rename from src/core/prelude/string/spec.js rename to src/core/prelude/string/spec.ts diff --git a/src/core/prelude/structures/sync-promise/spec.js b/src/core/prelude/structures/sync-promise/spec.ts similarity index 93% rename from src/core/prelude/structures/sync-promise/spec.js rename to src/core/prelude/structures/sync-promise/spec.ts index 53bb58c21..23ded8e43 100644 --- a/src/core/prelude/structures/sync-promise/spec.js +++ b/src/core/prelude/structures/sync-promise/spec.ts @@ -66,8 +66,8 @@ describe('core/prelude/structures/sync-promise', () => { new Promise((r) => setTimeout(() => r(SyncPromise.resolve(1)), 50)) ); }) - .then((val) => new Promise((r) => setTimeout(() => r(SyncPromise.resolve(val + 2)), 50))) - .then((val) => val * 2); + .then((val: number) => new Promise((r) => setTimeout(() => r(SyncPromise.resolve(val + 2)), 50))) + .then((val: number) => val * 2); expect(i).toBe(6); }); @@ -81,8 +81,8 @@ describe('core/prelude/structures/sync-promise', () => { new Promise((r) => setTimeout(() => r(SyncPromise.resolve(1)), 50)) ); }) - .then((val) => new Promise((r) => setTimeout(() => r(SyncPromise.reject(val + 2)), 50))) - .catch((val) => Promise.reject(val * 2)); + .then((val: number) => new Promise((r) => setTimeout(() => r(SyncPromise.reject(val + 2)), 50))) + .catch((val: number) => Promise.reject(val * 2)); } catch (err) { i = err; @@ -117,7 +117,7 @@ describe('core/prelude/structures/sync-promise', () => { expect( await new SyncPromise((resolve) => { - resolve(new Promise((r) => setTimeout(() => r(1)), 100)); + resolve(new Promise((r) => setTimeout(() => r(1), 100))); resolve(2); }) ).toBe(1); @@ -136,7 +136,7 @@ describe('core/prelude/structures/sync-promise', () => { try { await new SyncPromise((resolve, reject) => { - reject(new Promise((r) => setTimeout(() => r(1)), 100)); + reject(new Promise((r) => setTimeout(() => r(1), 100))); reject(2); }); @@ -167,7 +167,7 @@ describe('core/prelude/structures/sync-promise', () => { new SyncPromise((resolve, reject) => { reject('boom'); }) - .then((val) => val * 2, (err) => { + .then((val: number) => val * 2, (err) => { expect(err).toBe('boom'); i += 2; }); @@ -204,7 +204,7 @@ describe('core/prelude/structures/sync-promise', () => { new SyncPromise((resolve, reject) => { reject('boom'); }) - .then((val) => val * 2) + .then((val: number) => val * 2) .catch((err) => { expect(err).toBe('boom'); i += 2; diff --git a/src/core/prelude/types/spec.js b/src/core/prelude/types/spec.ts similarity index 97% rename from src/core/prelude/types/spec.js rename to src/core/prelude/types/spec.ts index c075312fe..ab08653b3 100644 --- a/src/core/prelude/types/spec.js +++ b/src/core/prelude/types/spec.ts @@ -1,4 +1,8 @@ -/* eslint-disable no-empty-function, no-new-func */ +/* eslint-disable + no-empty-function, + no-new-func, + @typescript-eslint/no-empty-function, + @typescript-eslint/no-extraneous-class */ /*! * V4Fire Core @@ -61,9 +65,9 @@ describe('core/prelude/types', () => { expect(Object.isNumber(NaN)).toBe(true); expect(Object.isNumber(Object(0))).toBe(false); expect(Object.isNumber(null)).toBe(false); - if (typeof BigInt !== 'undefined') { - expect(Object.isNumber(1n)).toBe(false); + // eslint-disable-next-line no-eval + expect(Object.isNumber(eval('1n'))).toBe(false); } }); diff --git a/src/core/promise/abortable/spec.js b/src/core/promise/abortable/spec.ts similarity index 94% rename from src/core/promise/abortable/spec.js rename to src/core/promise/abortable/spec.ts index 1d42a1da2..107f933db 100644 --- a/src/core/promise/abortable/spec.js +++ b/src/core/promise/abortable/spec.ts @@ -32,8 +32,8 @@ describe('core/promise/abortable', () => { new Promise((r) => setTimeout(() => r(AbortablePromise.resolve(1)), 50)) ); }) - .then((val) => new Promise((r) => setTimeout(() => r(AbortablePromise.resolve(val + 2)), 50))) - .then((val) => val * 2); + .then((val: number) => new Promise((r) => setTimeout(() => r(AbortablePromise.resolve(val + 2)), 50))) + .then((val: number) => val * 2); expect(i).toBe(6); }); @@ -47,8 +47,8 @@ describe('core/promise/abortable', () => { new Promise((r) => setTimeout(() => r(AbortablePromise.resolve(1)), 50)) ); }) - .then((val) => new Promise((r) => setTimeout(() => r(AbortablePromise.reject(val + 2)), 50))) - .catch((val) => Promise.reject(val * 2)); + .then((val: number) => new Promise((r) => setTimeout(() => r(AbortablePromise.reject(val + 2)), 50))) + .catch((val: number) => Promise.reject(val * 2)); } catch (err) { i = err; @@ -83,7 +83,7 @@ describe('core/promise/abortable', () => { expect( await new AbortablePromise((resolve) => { - resolve(new Promise((r) => setTimeout(() => r(1)), 100)); + resolve(new Promise((r) => setTimeout(() => r(1), 100))); resolve(2); }) ).toBe(1); @@ -102,7 +102,7 @@ describe('core/promise/abortable', () => { try { await new AbortablePromise((resolve, reject) => { - reject(new Promise((r) => setTimeout(() => r(1)), 100)); + reject(new Promise((r) => setTimeout(() => r(1), 100))); reject(2); }); @@ -217,7 +217,7 @@ describe('core/promise/abortable', () => { await new AbortablePromise((resolve, reject) => { reject('boom'); }) - .then((val) => val * 2, (err) => { + .then((val: number) => val * 2, (err) => { expect(err).toBe('boom'); i += 2; }); @@ -254,7 +254,7 @@ describe('core/promise/abortable', () => { await new AbortablePromise((resolve, reject) => { reject('boom'); }) - .then((val) => val * 2) + .then((val: number) => val * 2) .catch((err) => { expect(err).toBe('boom'); i += 2; diff --git a/src/core/promise/spec.js b/src/core/promise/spec.ts similarity index 98% rename from src/core/promise/spec.js rename to src/core/promise/spec.ts index b8572a594..23051c1f7 100644 --- a/src/core/promise/spec.js +++ b/src/core/promise/spec.ts @@ -48,7 +48,7 @@ describe('core/promise', () => { }); it('providing a custom promise executor', async () => { - const promise = createControllablePromise({ + const promise = createControllablePromise({ executor: (resolve) => resolve(5) }); diff --git a/src/core/promise/sync/spec.js b/src/core/promise/sync/spec.ts similarity index 100% rename from src/core/promise/sync/spec.js rename to src/core/promise/sync/spec.ts diff --git a/src/core/queue/merge/spec.js b/src/core/queue/merge/spec.ts similarity index 96% rename from src/core/queue/merge/spec.js rename to src/core/queue/merge/spec.ts index 64546ea0c..37a990d54 100644 --- a/src/core/queue/merge/spec.js +++ b/src/core/queue/merge/spec.ts @@ -82,7 +82,7 @@ describe('core/queue/merge', () => { clonedQueue = queue.clone(); expect(queue !== clonedQueue).toBe(true); - expect(queue.innerQueue !== clonedQueue.innerQueue).toBe(true); + expect(queue['innerQueue'] !== clonedQueue['innerQueue']).toBe(true); expect(queue.head).toBe(item); expect(queue.length).toBe(1); diff --git a/src/core/queue/order/spec.js b/src/core/queue/order/spec.ts similarity index 83% rename from src/core/queue/order/spec.js rename to src/core/queue/order/spec.ts index 6f922ea3d..8981ab1c4 100644 --- a/src/core/queue/order/spec.js +++ b/src/core/queue/order/spec.ts @@ -11,7 +11,7 @@ import OrderQueue from 'core/queue/order'; describe('core/queue/order', () => { it('should put and remove elements from the queue in the correct order', () => { const - queue = new OrderQueue((a, b) => a - b); + queue = new OrderQueue((a, b) => a - b); expect(queue.push(7)).toBe(1); expect(queue.push(2)).toBe(2); @@ -28,7 +28,7 @@ describe('core/queue/order', () => { it('should return the queue length', () => { const - queue = new OrderQueue((a, b) => a - b); + queue = new OrderQueue((a, b) => a - b); queue.push(7); queue.push(2); @@ -41,7 +41,7 @@ describe('core/queue/order', () => { it('should implement the alternative API', () => { const - queue = new OrderQueue((a, b) => b - a); + queue = new OrderQueue((a, b) => b - a); expect(queue.unshift(7)).toBe(1); expect(queue.unshift(2)).toBe(2); @@ -58,7 +58,7 @@ describe('core/queue/order', () => { it('should implement the iterable API', () => { const - queue = new OrderQueue((a, b) => a - b); + queue = new OrderQueue((a, b) => a - b); queue.push(5); queue.push(1); @@ -71,7 +71,7 @@ describe('core/queue/order', () => { it('calling `clone` should clone the queue', () => { const - queue = new OrderQueue((a, b) => a - b); + queue = new OrderQueue((a, b) => a - b); queue.push(3); @@ -86,12 +86,12 @@ describe('core/queue/order', () => { expect(clonedQueue.length).toBe(1); expect(clonedQueue.pop()).toBe(3); - expect(queue.comparator === clonedQueue.comparator).toBe(true); + expect(queue['comparator'] === clonedQueue['comparator']).toBe(true); }); it('calling `clear` should clear the queue', () => { const - queue = new OrderQueue((a, b) => a - b); + queue = new OrderQueue((a, b) => a - b); queue.push(3); queue.push(4); diff --git a/src/core/queue/simple/spec.js b/src/core/queue/simple/spec.ts similarity index 97% rename from src/core/queue/simple/spec.js rename to src/core/queue/simple/spec.ts index f94700211..378ea35f1 100644 --- a/src/core/queue/simple/spec.js +++ b/src/core/queue/simple/spec.ts @@ -96,7 +96,7 @@ describe('core/queue/simple', () => { clonedQueue = queue.clone(); expect(queue !== clonedQueue).toBe(true); - expect(queue.innerQueue !== clonedQueue.innerQueue).toBe(true); + expect(queue['innerQueue'] !== clonedQueue['innerQueue']).toBe(true); expect(queue.head).toBe(el); expect(queue.length).toBe(1); diff --git a/src/core/queue/worker/interface.ts b/src/core/queue/worker/interface.ts index f12e9458c..be6d7004d 100644 --- a/src/core/queue/worker/interface.ts +++ b/src/core/queue/worker/interface.ts @@ -90,7 +90,7 @@ export default abstract class WorkerQueue extends AbstractQueue< * @param worker * @param [opts] - additional options */ - protected constructor(worker: QueueWorker, opts: WorkerQueueOptions = {}) { + constructor(worker: QueueWorker, opts: WorkerQueueOptions = {}) { super(); this.worker = worker; diff --git a/src/core/queue/worker/merge/spec.js b/src/core/queue/worker/merge/spec.ts similarity index 66% rename from src/core/queue/worker/merge/spec.js rename to src/core/queue/worker/merge/spec.ts index cd636a578..08007eea4 100644 --- a/src/core/queue/worker/merge/spec.js +++ b/src/core/queue/worker/merge/spec.ts @@ -11,9 +11,9 @@ import MergeQueue from 'core/queue/worker/merge'; describe('core/queue/worker/merge', () => { it('should put and remove elements from the queue in the correct order', async () => { const - res = []; + res: number[] = []; - const queue = new MergeQueue((task) => { + const queue = new MergeQueue((task: {a: number}) => { res.push(task.a); return Promise.resolve(); @@ -26,15 +26,15 @@ describe('core/queue/worker/merge', () => { expect(queue.push({a: 1})) .toBeInstanceOf(Promise); - queue.push({a: 1}); - queue.push({a: 2}); - queue.push({a: 3}); + await queue.push({a: 1}); + await queue.push({a: 2}); + await queue.push({a: 3}); expect(queue.length).toBe(1); expect(queue.head).toEqual({a: 3}); expect(queue.pop()).toEqual({a: 3}); - queue.push({a: 4}); + await queue.push({a: 4}); await queue.push({a: 4}).then(() => { expect(queue.length).toBe(0); expect(res).toEqual([1, 2, 4]); @@ -43,9 +43,9 @@ describe('core/queue/worker/merge', () => { it('should implement the alternative API', async () => { const - res = []; + res: number[] = []; - const queue = new MergeQueue((task) => { + const queue = new MergeQueue((task: {a: number}) => { res.push(task.a); return Promise.resolve(); @@ -58,15 +58,15 @@ describe('core/queue/worker/merge', () => { expect(queue.unshift({a: 1})) .toBeInstanceOf(Promise); - queue.unshift({a: 1}); - queue.unshift({a: 2}); - queue.unshift({a: 3}); + await queue.unshift({a: 1}); + await queue.unshift({a: 2}); + await queue.unshift({a: 3}); expect(queue.length).toBe(1); expect(queue.head).toEqual({a: 3}); expect(queue.shift()).toEqual({a: 3}); - queue.unshift({a: 4}); + await queue.unshift({a: 4}); await queue.unshift({a: 4}).then(() => { expect(queue.length).toBe(0); expect(res).toEqual([1, 2, 4]); @@ -75,17 +75,17 @@ describe('core/queue/worker/merge', () => { it('should implement the iterable API', async () => { const - res = []; + res: number[] = []; - const queue = new MergeQueue((task) => { + const queue = new MergeQueue((task: {a: number}) => { res.push(task.a); return Promise.resolve(); }, {concurrency: 2}); - queue.unshift({a: 1}); - queue.unshift({a: 2}); - queue.unshift({a: 3}); + await queue.unshift({a: 1}); + await queue.unshift({a: 2}); + await queue.unshift({a: 3}); const iterate = async () => { let @@ -103,19 +103,19 @@ describe('core/queue/worker/merge', () => { await expect(iterate()).resolves.toEqual([1, 2, 3]); }); - it('calling `clone` should clone the queue', () => { + it('calling `clone` should clone the queue', async () => { const queue = new MergeQueue(Promise.resolve, {concurrency: 1}); - queue.unshift({a: 1}); - queue.unshift({a: 2}); - queue.unshift({a: 3}); + await queue.unshift({a: 1}); + await queue.unshift({a: 2}); + await queue.unshift({a: 3}); const clonedQueue = queue.clone(); expect(queue !== clonedQueue).toBe(true); - expect(queue.tasks !== clonedQueue.tasks).toBe(true); - expect(queue.tasksMap !== clonedQueue.tasksMap).toBe(true); + expect(queue['tasks'] !== clonedQueue['tasks']).toBe(true); + expect(queue['tasksMap'] !== clonedQueue['tasksMap']).toBe(true); expect(queue.length).toBe(2); expect(queue.shift()).toEqual({a: 2}); @@ -124,19 +124,19 @@ describe('core/queue/worker/merge', () => { expect(clonedQueue.length).toBe(2); }); - it('calling `clear` should clear the queue', () => { + it('calling `clear` should clear the queue', async () => { const - res = []; + res: number[] = []; - const queue = new MergeQueue((task) => { + const queue = new MergeQueue((task: {a: number}) => { res.push(task.a); return Promise.resolve(); }, {concurrency: 1}); - queue.unshift({a: 1}); - queue.unshift({a: 2}); - queue.unshift({a: 3}); + await queue.unshift({a: 1}); + await queue.unshift({a: 2}); + await queue.unshift({a: 3}); expect(queue.length).toBe(2); diff --git a/src/core/queue/worker/simple/spec.js b/src/core/queue/worker/simple/spec.ts similarity index 69% rename from src/core/queue/worker/simple/spec.js rename to src/core/queue/worker/simple/spec.ts index bb4e7e14d..9cc00dd18 100644 --- a/src/core/queue/worker/simple/spec.js +++ b/src/core/queue/worker/simple/spec.ts @@ -11,9 +11,9 @@ import WorkerQueue from 'core/queue/worker/simple'; describe('core/queue/worker/simple', () => { it('should put and remove elements from the queue in the correct order', async () => { const - res = []; + res: number[] = []; - const queue = new WorkerQueue((task) => { + const queue = new WorkerQueue((task: {a: number}) => { res.push(task.a); return Promise.resolve(); @@ -25,8 +25,8 @@ describe('core/queue/worker/simple', () => { expect(queue.push({a: 1})) .toBeInstanceOf(Promise); - queue.push({a: 2}); - queue.push({a: 3}); + await queue.push({a: 2}); + await queue.push({a: 3}); expect(queue.length).toBe(1); expect(queue.head).toEqual({a: 3}); @@ -40,23 +40,22 @@ describe('core/queue/worker/simple', () => { it('should implement the alternative API', async () => { const - res = []; + res: number[] = []; - const queue = new WorkerQueue((task) => { + const queue = new WorkerQueue((task: {a: number}) => { res.push(task.a); return Promise.resolve(); }, { concurrency: 2, - refreshInterval: 50, - hashFn: (task) => JSON.stringify(task) + refreshInterval: 50 }); expect(queue.unshift({a: 1})) .toBeInstanceOf(Promise); - queue.unshift({a: 2}); - queue.unshift({a: 3}); + await queue.unshift({a: 2}); + await queue.unshift({a: 3}); expect(queue.length).toBe(1); expect(queue.head).toEqual({a: 3}); @@ -70,17 +69,17 @@ describe('core/queue/worker/simple', () => { it('should implement the iterable API', async () => { const - res = []; + res: number[] = []; - const queue = new WorkerQueue((task) => { + const queue = new WorkerQueue((task: {a: number}) => { res.push(task.a); return Promise.resolve(); }, {concurrency: 2}); - queue.unshift({a: 1}); - queue.unshift({a: 2}); - queue.unshift({a: 3}); + await queue.unshift({a: 1}); + await queue.unshift({a: 2}); + await queue.unshift({a: 3}); const iterate = async () => { let @@ -98,18 +97,18 @@ describe('core/queue/worker/simple', () => { await expect(iterate()).resolves.toEqual([1, 2, 3]); }); - it('calling `clone` should clone the queue', () => { + it('calling `clone` should clone the queue', async () => { const queue = new WorkerQueue(Promise.resolve, {concurrency: 1}); - queue.unshift({a: 1}); - queue.unshift({a: 2}); - queue.unshift({a: 3}); + await queue.unshift({a: 1}); + await queue.unshift({a: 2}); + await queue.unshift({a: 3}); const clonedQueue = queue.clone(); expect(queue !== clonedQueue).toBe(true); - expect(queue.tasks !== clonedQueue.tasks).toBe(true); + expect(queue['tasks'] !== clonedQueue['tasks']).toBe(true); expect(queue.length).toBe(2); expect(queue.shift()).toEqual({a: 2}); @@ -118,19 +117,19 @@ describe('core/queue/worker/simple', () => { expect(clonedQueue.length).toBe(2); }); - it('calling `clear` should clear the queue', () => { + it('calling `clear` should clear the queue', async () => { const - res = []; + res: number[] = []; - const queue = new WorkerQueue((task) => { + const queue = new WorkerQueue((task: {a: number}) => { res.push(task.a); return Promise.resolve(); }, {concurrency: 1}); - queue.unshift({a: 1}); - queue.unshift({a: 2}); - queue.unshift({a: 3}); + await queue.unshift({a: 1}); + await queue.unshift({a: 2}); + await queue.unshift({a: 3}); expect(queue.length).toBe(2); diff --git a/src/core/range/index.ts b/src/core/range/index.ts index 61e02993d..9a6da5873 100644 --- a/src/core/range/index.ts +++ b/src/core/range/index.ts @@ -11,7 +11,7 @@ * @packageDocumentation */ -import type { RangeValue, RangeType } from 'core/range/interface'; +import type { RangeValue, RangeType, CompatibleTypes } from 'core/range/interface'; export * from 'core/range/interface'; @@ -254,7 +254,7 @@ export default class Range { * console.log(new Range(0, 10).intersect(new Range('a', 'z')).toString()); * ``` */ - intersect(range: Range): Range { + intersect>(range: Range): Range { const start = Math.max(this.start, range.start), end = Math.min(this.end, range.end); @@ -299,7 +299,7 @@ export default class Range { * console.log(new Range(0, 10).union(new Range('a', 'z')).toString()); * ``` */ - union(range: Range): Range { + union>(range: Range): Range { if (this.type !== range.type) { return new Range(0, [0]); } diff --git a/src/core/range/interface.ts b/src/core/range/interface.ts index f39d20dfa..83695bef0 100644 --- a/src/core/range/interface.ts +++ b/src/core/range/interface.ts @@ -15,3 +15,6 @@ export type RangeType = 'number' | 'string' | 'date'; + +export type CompatibleTypes = + Type extends string ? string : Type extends number ? number : Date; diff --git a/src/core/range/spec.js b/src/core/range/spec.ts similarity index 95% rename from src/core/range/spec.js rename to src/core/range/spec.ts index 5b2675134..9be0faa43 100644 --- a/src/core/range/spec.js +++ b/src/core/range/spec.ts @@ -27,8 +27,8 @@ describe('core/range', () => { it('string range', () => { expect(new Range('a', 'e').toArray()).toEqual(['a', 'b', 'c', 'd', 'e']); - expect(new Range('a', 'e'.codePointAt(0) - 2).toArray()).toEqual(['a', 'b', 'c']); - expect(new Range('a'.codePointAt(0) + 2, 'e').toArray()).toEqual(['c', 'd', 'e']); + expect(new Range('a', 'e'.codePointAt(0)! - 2).toArray()).toEqual(['a', 'b', 'c']); + expect(new Range('a'.codePointAt(0)! + 2, 'e').toArray()).toEqual(['c', 'd', 'e']); }); it('string range without including of bounds', () => { @@ -37,7 +37,7 @@ describe('core/range', () => { it('string range (extended Unicode)', () => { expect(new Range('😁', '😅').toArray()).toEqual(['😁', '😂', '😃', '😄', '😅']); - expect(new Range('😁', '😅'.codePointAt(0) - 2).toArray()).toEqual(['😁', '😂', '😃']); + expect(new Range('😁', '😅'.codePointAt(0)! - 2).toArray()).toEqual(['😁', '😂', '😃']); }); it('string range (extended Unicode) without including of bounds', () => { @@ -177,7 +177,7 @@ describe('core/range', () => { expect(new Range(1).intersect(new Range([1], 3)).toArray()) .toEqual([2, 3]); - expect(new Range(1, 10000).intersect(new Range('a', 'z')).toArray()) + expect(new Range(1, 10000).intersect(>new Range('a', 'z')).toArray()) .toEqual([]); }); @@ -197,7 +197,7 @@ describe('core/range', () => { expect(new Range(2).union(new Range(3, 2)).toString()) .toBe('2..'); - expect(new Range(1, 10000).union(new Range('a', 'z')).toArray()) + expect(new Range(1, 10000).union(>new Range('a', 'z')).toArray()) .toEqual([]); }); diff --git a/src/core/request/engines/provider/spec.js b/src/core/request/engines/provider/spec.ts similarity index 77% rename from src/core/request/engines/provider/spec.js rename to src/core/request/engines/provider/spec.ts index ef877485a..15973f0ca 100644 --- a/src/core/request/engines/provider/spec.js +++ b/src/core/request/engines/provider/spec.ts @@ -10,13 +10,13 @@ import express from 'express'; import { set, get } from 'core/env'; -import request, { globalOpts } from 'core/request'; +import request, { globalOpts, MiddlewareParams } from 'core/request'; import Provider, { provider } from 'core/data'; import createProviderEngine from 'core/request/engines/provider'; @provider class ProviderEngineTestBaseProvider extends Provider { - static request = Provider.request({ + static override request: typeof Provider.request = Provider.request({ api: { url: 'http://localhost:3000' } @@ -25,39 +25,39 @@ class ProviderEngineTestBaseProvider extends Provider { @provider class ProviderEngineTestDataProvider extends Provider { - static request = Provider.request({ + static override request: typeof Provider.request = Provider.request({ engine: createProviderEngine(ProviderEngineTestBaseProvider) }); - baseURL = '/data'; + override baseURL: string = '/data'; } @provider class ProviderEngineTestJSONProvider extends Provider { - static request = Provider.request({ + static override request: typeof Provider.request = Provider.request({ engine: createProviderEngine(ProviderEngineTestDataProvider, { peek: 'get' }) }); - baseURL = 'json'; + override baseURL: string = 'json'; } @provider class ProviderEngineTestDecodersProvider extends Provider { - static request = Provider.request({ + static override request: typeof Provider.request = Provider.request({ engine: createProviderEngine(ProviderEngineTestJSONProvider) }); - static encoders = { - post(data) { + static override encoders: typeof Provider.encoders = { + post(data: Dictionary) { data.id = 12345; return data; } }; - static decoders = { - post(data) { + static override decoders: typeof Provider.decoders = { + post(data: Dictionary) { data.message = 'ok'; return data; } @@ -66,36 +66,38 @@ class ProviderEngineTestDecodersProvider extends Provider { @provider class ProviderEngineTestMiddlewareProvider extends Provider { - static request = Provider.request({ + static override request: typeof Provider.request = Provider.request({ engine: createProviderEngine(ProviderEngineTestDecodersProvider) }); - static decoders = { - post(data) { + static override decoders: typeof Provider.decoders= { + post(data: Dictionary) { data.error = false; return data; } }; - static middlewares = { - fakeResponse({ctx}) { - ctx.params.body.value = ctx.params.body.value.join('-'); + static override middlewares: typeof Provider.middlewares = { + fakeResponse({ctx}: MiddlewareParams) { + if (Object.isDictionary(ctx.params.body)) { + ctx.params.body.value = (ctx.params.body.value).join('-'); + } } - } + }; } @provider class ProviderEngineTestBasePathProvider extends ProviderEngineTestDataProvider { - baseURL = '/data/:id'; + override baseURL: string = '/data/:id'; } @provider class ProviderEngineTestPathProvider extends Provider { - static request = Provider.request({ + static override request: typeof Provider.request = Provider.request({ engine: createProviderEngine(ProviderEngineTestBasePathProvider) }); - baseURL = '/:id'; + override baseURL: string = '/:id'; } describe('core/request/engine/provider', () => { @@ -145,7 +147,7 @@ describe('core/request/engine/provider', () => { }); it('response type is correct for XML', async () => { - expect((await dataProvider.get().data).querySelector('foo').textContent) + expect((await dataProvider.get().data)?.querySelector('foo')?.textContent) .toBe('Hello world'); }); diff --git a/src/core/request/headers/spec.js b/src/core/request/headers/spec.ts similarity index 100% rename from src/core/request/headers/spec.js rename to src/core/request/headers/spec.ts diff --git a/src/core/request/interface.ts b/src/core/request/interface.ts index 0f290eecd..5affdcc55 100644 --- a/src/core/request/interface.ts +++ b/src/core/request/interface.ts @@ -97,7 +97,7 @@ export interface WrappedEncoder { (data: I): CanPromise; } -export type Encoders = Iterable; +export type Encoders = Iterable>; export type WrappedEncoders = Iterable; export interface Decoder { @@ -108,7 +108,7 @@ export interface WrappedDecoder { (data: I, response: Response): CanPromise; } -export type Decoders = Iterable; +export type Decoders = Iterable>; export type WrappedDecoders = Iterable; export interface StreamDecoder { @@ -159,7 +159,7 @@ export interface RequestResolver { (url: string, params: MiddlewareParams, ...args: ARGS): ResolverResult; } -export type ResolverResult = CanUndef>; +export type ResolverResult = CanUndef | string>; /** * Options for a request @@ -453,7 +453,7 @@ export interface CreateRequestOptions { * and returns new data to respond. If you provide a sequence of functions, * the first function will pass a result to the next function from the sequence, etc. */ - decoder?: Decoder | Decoders; + decoder?: Decoder | Decoders; /** * A function (or a sequence of functions) takes the current request response data chunk diff --git a/src/core/request/modules/stream-buffer/spec.js b/src/core/request/modules/stream-buffer/spec.ts similarity index 95% rename from src/core/request/modules/stream-buffer/spec.js rename to src/core/request/modules/stream-buffer/spec.ts index 42c622eb5..ec7e0b1ea 100644 --- a/src/core/request/modules/stream-buffer/spec.js +++ b/src/core/request/modules/stream-buffer/spec.ts @@ -59,14 +59,14 @@ describe('core/request/modules/stream-buffer', () => { it('closing the stream should finish a registered asynchronous iterator', async () => { const - streamBuffer = new StreamBuffer(), + streamBuffer = new StreamBuffer(), queue = globalChunks.slice(), - chunks = []; + chunks: string[] = []; setTimeout(function cb() { - streamBuffer.add(queue.shift()); + streamBuffer.add(queue.shift()!); - if (queue.length) { + if (queue.length > 0) { setTimeout(cb, 50); } else { diff --git a/src/core/request/spec.js b/src/core/request/spec.ts similarity index 79% rename from src/core/request/spec.js rename to src/core/request/spec.ts index d191dc612..81581011f 100644 --- a/src/core/request/spec.js +++ b/src/core/request/spec.ts @@ -14,8 +14,8 @@ import { set, get } from 'core/env'; import { sequence } from 'core/iter/combinators'; import { pick, andPick, assemble, streamArray } from 'core/json/stream'; -import Provider, { provider } from 'core/data'; -import baseRequest, { globalOpts, RequestError } from 'core/request'; +import Provider, { MiddlewareParams, provider } from 'core/data'; +import baseRequest, { globalOpts, RequestEngine, RequestError } from 'core/request'; import { defaultRequestOpts } from 'core/request/const'; import Response from 'core/request/response'; @@ -25,10 +25,12 @@ import nodeEngine from 'core/request/engines/node'; import fetchEngine from 'core/request/engines/fetch'; import xhrEngine from 'core/request/engines/xhr'; import createProviderEngine from 'core/request/engines/provider'; +import type { Server } from 'http'; +import type { Token } from 'core/json/stream/parser'; @provider class TestRequestChainProvider extends Provider { - static request = Provider.request({ + static override request: typeof Provider.request = Provider.request({ engine: createProviderEngine(Provider) }); } @@ -37,6 +39,34 @@ const emptyBodyStatuses = [204, 304], faviconBase64 = 'AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAnISL6JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL5JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL1JyEi9ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEihCchIpgnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEixCUgIRMmICEvJyEi5ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIrYnISKSJyEi9ichIlxQREUAHxobAichIo4nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISJeJyEiICchIuAnISJJJiAhbCYgITgmICEnJyEi4ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEiXichIiAnISLdJyEihichIuknISKkIRwdBCchIoUnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIl4nISIgJyEi4ichIu4nISL/JyEi8CYgIT8mICEhJyEi3CchIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISJeJyEiHychIuUnISL/JyEi/ychIv8nISKrIh0eBiYhInwnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEiXSYgITUnISLvJyEi/ychIv8nISL/JyEi9CYgIUcmICEbJyEi1ichIv8nISL/JyEi/ychIv8nISL/JyEi/ichImknISKjJyEi/ychIv8nISL/JyEi/ychIv8nISKzIRwdBiYhIX0nISL/JyEi/ychIv8nISL/JyEi/ychIvwnISK+JyEi9CchIv8nISL/JyEi/ychIv8nISL/JyEi9yYhIoonISKzJyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL6JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='; +interface ResponseFavicon { + type: string; + size: number; +} + +interface ResponseJson1 { + id: number; + value: string; +} + +interface ResponseJson2 { + message: string; +} + +interface ResponseJson { + message: string; +} + +interface ResponseJsonUsers { + total: number; + data: Array<{name: string; age: number}>; +} + +interface ResponseRetry { + tryNumber: number; + times: number; +} + describe('core/request', () => { const engines = new Map([ ['node', nodeEngine], @@ -47,13 +77,13 @@ describe('core/request', () => { ]); let - request, - defaultEngine, - logOptions; + request: typeof baseRequest, + defaultEngine: RequestEngine, + logOptions: CanUndef; let - api, - server; + api: Nullable, + server: CanUndef; beforeAll(async () => { api = globalOpts.api; @@ -66,7 +96,7 @@ describe('core/request', () => { }); beforeEach(() => { - if (server) { + if (server != null) { server.close(); } @@ -76,10 +106,10 @@ describe('core/request', () => { afterAll(async () => { globalOpts.api = api; - await server.close(); + await server?.close(); defaultRequestOpts.engine = defaultEngine; - set('log', logOptions); + set('log', logOptions ?? {}); }); // eslint-disable-next-line max-lines-per-function @@ -98,10 +128,10 @@ describe('core/request', () => { it('blob `get`', async () => { const - data = await request('http://localhost:4000/favicon.ico').data; + data = await request('http://localhost:4000/favicon.ico').data; - expect(data.type).toBe('image/x-icon'); - expect(data.size).toBe(1150); + expect(data?.type).toBe('image/x-icon'); + expect(data?.size).toBe(1150); }); it('json `get`', async () => { @@ -112,12 +142,12 @@ describe('core/request', () => { it('json `get` with caching', async () => { const url = 'http://localhost:4000/json/1', - get = request({cacheStrategy: 'forever', cacheTTL: 10}); + get = request({cacheStrategy: 'forever', cacheTTL: 10}); - await get(url).data; + await get(url).data; const - req = await get(url); + req = await get(url); expect(req.cache).toBe('memory'); expect(await req.data).toEqual({id: 1, value: 'things'}); @@ -126,7 +156,7 @@ describe('core/request', () => { setTimeout(async () => { { const - req = await get(url); + req = await get(url); expect(req.cache).toBeUndefined(); expect(await req.data).toEqual({id: 1, value: 'things'}); @@ -135,34 +165,34 @@ describe('core/request', () => { { const - req = await get(url); + req = await get(url); expect(req.cache).toBeUndefined(); expect(await req.data).toEqual({id: 1, value: 'things'}); } - resolve(); + resolve(null); }, 15); })); }); it('text/xml `get`', async () => { - const data = await request('http://localhost:4000/xml/text').data; - expect(data.querySelector('foo').textContent).toBe('Hello world'); + const data = await request('http://localhost:4000/xml/text').data; + expect(data?.querySelector('foo')?.textContent).toBe('Hello world'); }); it('application/xml `get`', async () => { - const data = await request('http://localhost:4000/xml/app').data; - expect(data.querySelector('foo').textContent).toBe('Hello world'); + const data = await request('http://localhost:4000/xml/app').data; + expect(data?.querySelector('foo')?.textContent).toBe('Hello world'); }); it('xml `get` with a query', async () => { - const data = await request('http://localhost:4000/search', {query: {q: 'bla'}}).data; - expect(data.querySelector('results').children[0].textContent).toBe('one'); + const data = await request('http://localhost:4000/search', {query: {q: 'bla'}}).data; + expect(data?.querySelector('results')?.children[0].textContent).toBe('one'); }); it('json `post`', async () => { - const req = await request('http://localhost:4000/json', { + const req = await request('http://localhost:4000/json', { method: 'POST', body: { id: 12345, @@ -185,7 +215,7 @@ describe('core/request', () => { err; try { - await request('http://localhost:4000/json', { + await request('http://localhost:4000/json', { method: 'POST', okStatuses: 200, body: { @@ -206,18 +236,28 @@ describe('core/request', () => { }); it('json `post` with encoders/decoders', async () => { - const req = await request('http://localhost:4000/json', { + interface RequestBody { + id?: number; + value?: string | string[]; + } + + const req = await request('http://localhost:4000/json', { method: 'POST', encoder: [ (data) => { - data.id = 12345; - return Promise.resolve(data); + const req = data; + req.id = 12345; + return Promise.resolve(req); }, (data) => { - data.value = data.value.join('-'); - return data; + const req = data; + if (Object.isArray(req.value)) { + req.value = req.value.join('-'); + } + + return req; } ], @@ -239,16 +279,20 @@ describe('core/request', () => { }); it('json `post` with middlewares', async () => { - const req = await request('http://localhost:4000/json', { + const req = await request('http://localhost:4000/json', { method: 'POST', middlewares: { - addId({opts}) { - opts.body.id = 12345; + addId({opts}: MiddlewareParams) { + if (Object.isDictionary(opts.body) && 'id' in opts.body) { + opts.body.id = 12345; + } }, - serializeValue({opts}) { - opts.body.value = opts.body.value.join('-'); + serializeValue({opts}: MiddlewareParams) { + if (Object.isDictionary(opts.body) && 'value' in opts.body) { + opts.body.value = (opts.body.value).join('-'); + } } }, @@ -269,7 +313,7 @@ describe('core/request', () => { method: 'POST', middlewares: { - fakeResponse({ctx}) { + fakeResponse({ctx}: MiddlewareParams) { return () => ctx.wrapAsResponse({message: 'fake'}); } }, @@ -287,7 +331,7 @@ describe('core/request', () => { }); it('json `put` with headers', async () => { - const req = await request('http://localhost:4000/json/2', { + const req = await request('http://localhost:4000/json/2', { method: 'PUT', headers: { Accept: 'application/json' @@ -333,10 +377,10 @@ describe('core/request', () => { let resolvedUrl; - const engine = (params) => { + const engine = ((params) => { resolvedUrl = params.url; return Promise.resolve(new Response('')); - }; + }); await request('/then', { api: { @@ -463,14 +507,14 @@ describe('core/request', () => { }); it('retrying of a request', async () => { - const req = request('http://localhost:4000/retry', { + const req = request('http://localhost:4000/retry', { retry: { attempts: 5, delay: () => 0 } }); - const body = await (await req).response.json(); + const body = await (await req).response.json(); expect(body.tryNumber).toBe(4); }); @@ -483,14 +527,14 @@ describe('core/request', () => { }); it('retrying with a speed up response', async () => { - const req = await request('http://localhost:4000/retry/speedup', { + const req = await request('http://localhost:4000/retry/speedup', { timeout: 300, retry: 2 }); expect(req.response.ok).toBe(true); - const body = await req.response.json(); + const body = await req.response.json(); expect(body.tryNumber).toBe(2); }); @@ -548,12 +592,12 @@ describe('core/request', () => { it('request promise is an async iterable object', async () => { const - chunkLengths = [], - req = request('http://localhost:4000/favicon.ico'); + chunkLengths: number[] = [], + req = request('http://localhost:4000/favicon.ico'); let loadedBefore = 0, - totalLength; + totalLength: CanUndef; for await (const {loaded, total} of req) { if (totalLength == null) { @@ -571,12 +615,12 @@ describe('core/request', () => { it('request response is an async iterable object', async () => { const - chunkLengths = [], + chunkLengths: number[] = [], req = await request('http://localhost:4000/favicon.ico'); let loadedBefore = 0, - totalLength; + totalLength: CanUndef; for await (const {loaded, total} of req) { if (totalLength == null) { @@ -596,8 +640,8 @@ describe('core/request', () => { describe('listening XHR events', () => { it('`progress`', async () => { const - req = request('http://localhost:4000/json/1'), - events = []; + req = request('http://localhost:4000/json/1'), + events: string[] = []; req.emitter.on('progress', (e) => { events.push(e.type); @@ -612,7 +656,7 @@ describe('core/request', () => { it('`readystatechange`', async () => { const req = request('http://localhost:4000/json/1'), - events = []; + events: string[] = []; req.emitter.on('readystatechange', (e) => { events.push(e.type); @@ -645,15 +689,18 @@ describe('core/request', () => { }); it('parsing JSON from a stream', async () => { - const req = request('http://localhost:4000/json/users', { - streamDecoder: (data) => sequence( - assemble(pick(data, 'total')), - streamArray(andPick(data, 'data')) - ) + const req = request('http://localhost:4000/json/users', { + streamDecoder: (data) => { + const tokens = >data; + return sequence( + assemble(pick(tokens, 'total')), + streamArray(andPick(tokens, 'data')) + ); + } }); const - res = []; + res: any[] = []; for await (const token of await req.stream) { res.push(token); @@ -668,30 +715,40 @@ describe('core/request', () => { }); } - async function retryDelayTest(delay, delayMS) { + async function retryDelayTest(delay: () => number | Promise, delayMS: number) { const startTime = new Date().getTime(); - const req = request('http://localhost:4000/retry', { + const req = request('http://localhost:4000/retry', { retry: { attempts: 5, delay } }); + interface ResponseJson { + times: number[]; + } + + const res = await (await req).response.json(); + + if (!Object.isDictionary(res) || !res.hasOwnProperty('times')) { + throw new Error('response must have filed: times'); + } + const - body = await (await req).response.json(), + body = res, firstRequest = body.times[0]; const requestDelays = body.times.slice(1) - .reduce((acc, time, i) => acc.concat(time - firstRequest - i * delayMS), []); + .reduce((acc: number[], time, i) => acc.concat(time - firstRequest - i * delayMS), []); expect(firstRequest - startTime).toBeLessThan(delayMS); requestDelays.forEach((time) => expect(time).toBeGreaterThanOrEqual(delayMS)); } - async function convertStreamToBase64(stream) { + async function convertStreamToBase64(stream: any) { let - buffer = null, + buffer: Nullable = null, pos = 0; for await (const {data, loaded, total} of stream) { @@ -703,13 +760,13 @@ describe('core/request', () => { pos = loaded; } - return Buffer.from(buffer).toString('base64'); + return Buffer.from(buffer!).toString('base64'); } }); }); }); -function createServer() { +function createServer(): Server { const serverApp = express(); serverApp.use(express.json()); @@ -774,7 +831,7 @@ function createServer() { const {query} = req; - if (query.q != null && /^[A-Za-z0-9]*$/.test(query.q)) { + if (query.q != null && /^[A-Za-z0-9]*$/.test(query.q.toString())) { res.type('application/xml'); res.status(200); res.send('onetwothree'); @@ -803,7 +860,7 @@ function createServer() { const triesBeforeSuccess = 3, - requestTimes = []; + requestTimes: number[] = []; let tryNumber = 0, diff --git a/src/core/semver/spec.js b/src/core/semver/spec.ts similarity index 100% rename from src/core/semver/spec.js rename to src/core/semver/spec.ts diff --git a/src/core/symbol/spec.js b/src/core/symbol/spec.ts similarity index 100% rename from src/core/symbol/spec.js rename to src/core/symbol/spec.ts diff --git a/src/core/url/spec.js b/src/core/url/spec.ts similarity index 100% rename from src/core/url/spec.js rename to src/core/url/spec.ts diff --git a/src/core/xml/spec.js b/src/core/xml/spec.ts similarity index 91% rename from src/core/xml/spec.js rename to src/core/xml/spec.ts index e44fb429e..879375c73 100644 --- a/src/core/xml/spec.js +++ b/src/core/xml/spec.ts @@ -11,7 +11,7 @@ import { getDataTypeFromURI } from 'core/mime-type'; import { IS_NODE } from 'core/env'; describe('core/xml', () => { - it('`toDataURI`', () => { + it('`toDataURI`', async () => { let doc; @@ -19,7 +19,7 @@ describe('core/xml', () => { //#if node_js const - {JSDOM} = require('jsdom'), + {JSDOM} = await import('jsdom'), {document} = new JSDOM().window; doc = document; From b8b00a7bf313f7520958f7baf995cf762b835991 Mon Sep 17 00:00:00 2001 From: kz2d Date: Tue, 11 Oct 2022 14:17:29 +0300 Subject: [PATCH 10/20] first try --- index.d.ts | 4 +-- jest.config.ts | 2 +- src/core/prelude/date/format/spec.js | 11 +------ src/core/queue/worker/merge/spec.ts | 46 ++++++++++++++-------------- src/core/queue/worker/simple/spec.ts | 34 ++++++++++---------- src/core/request/spec.ts | 2 +- 6 files changed, 45 insertions(+), 54 deletions(-) diff --git a/index.d.ts b/index.d.ts index 7191c35c0..956381cc9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2460,7 +2460,7 @@ interface NumberConstructor { * Returns a curried version of `Number.pad` * @param opts - additional options */ - pad(opts: NumberPadOptions): (value: string) => string; + pad(opts: NumberPadOptions): (value: number) => string; /** * Returns a string from a number with adding extra zeros to the start, if necessary @@ -2707,7 +2707,7 @@ interface Number { * @param targetLength - length of the resulting string once the current string has been padded * @param [opts] - additional options */ - pad(targetLength?: number, opts?: NumberPadOptions): string; + pad(targetLength?: number | NumberPadOptions, opts?: NumberPadOptions): string; /** * Returns a string representation of the number by the specified pattern. diff --git a/jest.config.ts b/jest.config.ts index 7ceb10f3d..b8c2768e0 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -9,7 +9,7 @@ /** @type {import('ts-jest').InitialOptionsTsJest} */ export default { projects: [''], - testMatch: ['/dist/server/**/*[sS]pec.js', '/src/**/*[sS]pec.ts'], + testMatch: ['/dist/server/**/*[sS]pec.js'], rootDir: './', testTimeout: 20000, testEnvironment: 'node', diff --git a/src/core/prelude/date/format/spec.js b/src/core/prelude/date/format/spec.js index 5311109ed..3b70a1d6c 100644 --- a/src/core/prelude/date/format/spec.js +++ b/src/core/prelude/date/format/spec.js @@ -7,8 +7,7 @@ */ describe('core/prelude/date/format', () => { - const - date = Date.create('18.10.1989 10:10:10'); + const date = Date.create('18.10.1989 10:10:10'); it('`short`', () => { expect(date.short('en')).toBe('10/18/1989'); @@ -26,14 +25,6 @@ describe('core/prelude/date/format', () => { expect(Date.medium('en')(date)).toBe('October 18, 1989'); }); - it('`long`', () => { - expect(date.long('en')).toBe('October 18, 1989, 10:10:10 AM'); - }); - - it('`Date.long`', () => { - expect(Date.long('en')(date)).toBe('October 18, 1989, 10:10:10 AM'); - }); - it('`format`', () => { expect(date.format('Y;M:2-digit', 'en')).toBe('10/1989'); expect(date.format({year: 'numeric'})).toBe('1989'); diff --git a/src/core/queue/worker/merge/spec.ts b/src/core/queue/worker/merge/spec.ts index 08007eea4..6632612f6 100644 --- a/src/core/queue/worker/merge/spec.ts +++ b/src/core/queue/worker/merge/spec.ts @@ -9,7 +9,7 @@ import MergeQueue from 'core/queue/worker/merge'; describe('core/queue/worker/merge', () => { - it('should put and remove elements from the queue in the correct order', async () => { + it('should put and remove elements from the queue in the correct order', () => { const res: number[] = []; @@ -26,22 +26,22 @@ describe('core/queue/worker/merge', () => { expect(queue.push({a: 1})) .toBeInstanceOf(Promise); - await queue.push({a: 1}); - await queue.push({a: 2}); - await queue.push({a: 3}); + queue.push({a: 1}); + queue.push({a: 2}); + queue.push({a: 3}); expect(queue.length).toBe(1); expect(queue.head).toEqual({a: 3}); expect(queue.pop()).toEqual({a: 3}); - await queue.push({a: 4}); - await queue.push({a: 4}).then(() => { + queue.push({a: 4}); + queue.push({a: 4}).then(() => { expect(queue.length).toBe(0); expect(res).toEqual([1, 2, 4]); }); }); - it('should implement the alternative API', async () => { + it('should implement the alternative API', () => { const res: number[] = []; @@ -58,16 +58,16 @@ describe('core/queue/worker/merge', () => { expect(queue.unshift({a: 1})) .toBeInstanceOf(Promise); - await queue.unshift({a: 1}); - await queue.unshift({a: 2}); - await queue.unshift({a: 3}); + queue.unshift({a: 1}); + queue.unshift({a: 2}); + queue.unshift({a: 3}); expect(queue.length).toBe(1); expect(queue.head).toEqual({a: 3}); expect(queue.shift()).toEqual({a: 3}); - await queue.unshift({a: 4}); - await queue.unshift({a: 4}).then(() => { + queue.unshift({a: 4}); + queue.unshift({a: 4}).then(() => { expect(queue.length).toBe(0); expect(res).toEqual([1, 2, 4]); }); @@ -83,9 +83,9 @@ describe('core/queue/worker/merge', () => { }, {concurrency: 2}); - await queue.unshift({a: 1}); - await queue.unshift({a: 2}); - await queue.unshift({a: 3}); + queue.unshift({a: 1}); + queue.unshift({a: 2}); + queue.unshift({a: 3}); const iterate = async () => { let @@ -103,12 +103,12 @@ describe('core/queue/worker/merge', () => { await expect(iterate()).resolves.toEqual([1, 2, 3]); }); - it('calling `clone` should clone the queue', async () => { + it('calling `clone` should clone the queue', () => { const queue = new MergeQueue(Promise.resolve, {concurrency: 1}); - await queue.unshift({a: 1}); - await queue.unshift({a: 2}); - await queue.unshift({a: 3}); + queue.unshift({a: 1}); + queue.unshift({a: 2}); + queue.unshift({a: 3}); const clonedQueue = queue.clone(); @@ -124,7 +124,7 @@ describe('core/queue/worker/merge', () => { expect(clonedQueue.length).toBe(2); }); - it('calling `clear` should clear the queue', async () => { + it('calling `clear` should clear the queue', () => { const res: number[] = []; @@ -134,9 +134,9 @@ describe('core/queue/worker/merge', () => { }, {concurrency: 1}); - await queue.unshift({a: 1}); - await queue.unshift({a: 2}); - await queue.unshift({a: 3}); + queue.unshift({a: 1}); + queue.unshift({a: 2}); + queue.unshift({a: 3}); expect(queue.length).toBe(2); diff --git a/src/core/queue/worker/simple/spec.ts b/src/core/queue/worker/simple/spec.ts index 9cc00dd18..9463b94df 100644 --- a/src/core/queue/worker/simple/spec.ts +++ b/src/core/queue/worker/simple/spec.ts @@ -9,7 +9,7 @@ import WorkerQueue from 'core/queue/worker/simple'; describe('core/queue/worker/simple', () => { - it('should put and remove elements from the queue in the correct order', async () => { + it('should put and remove elements from the queue in the correct order', () => { const res: number[] = []; @@ -25,14 +25,14 @@ describe('core/queue/worker/simple', () => { expect(queue.push({a: 1})) .toBeInstanceOf(Promise); - await queue.push({a: 2}); - await queue.push({a: 3}); + queue.push({a: 2}); + queue.push({a: 3}); expect(queue.length).toBe(1); expect(queue.head).toEqual({a: 3}); expect(queue.pop()).toEqual({a: 3}); - await queue.push({a: 4}).then(() => { + queue.push({a: 4}).then(() => { expect(queue.length).toBe(0); expect(res).toEqual([1, 2, 4]); }); @@ -54,8 +54,8 @@ describe('core/queue/worker/simple', () => { expect(queue.unshift({a: 1})) .toBeInstanceOf(Promise); - await queue.unshift({a: 2}); - await queue.unshift({a: 3}); + queue.unshift({a: 2}); + queue.unshift({a: 3}); expect(queue.length).toBe(1); expect(queue.head).toEqual({a: 3}); @@ -77,9 +77,9 @@ describe('core/queue/worker/simple', () => { }, {concurrency: 2}); - await queue.unshift({a: 1}); - await queue.unshift({a: 2}); - await queue.unshift({a: 3}); + queue.unshift({a: 1}); + queue.unshift({a: 2}); + queue.unshift({a: 3}); const iterate = async () => { let @@ -97,12 +97,12 @@ describe('core/queue/worker/simple', () => { await expect(iterate()).resolves.toEqual([1, 2, 3]); }); - it('calling `clone` should clone the queue', async () => { + it('calling `clone` should clone the queue', () => { const queue = new WorkerQueue(Promise.resolve, {concurrency: 1}); - await queue.unshift({a: 1}); - await queue.unshift({a: 2}); - await queue.unshift({a: 3}); + queue.unshift({a: 1}); + queue.unshift({a: 2}); + queue.unshift({a: 3}); const clonedQueue = queue.clone(); @@ -117,7 +117,7 @@ describe('core/queue/worker/simple', () => { expect(clonedQueue.length).toBe(2); }); - it('calling `clear` should clear the queue', async () => { + it('calling `clear` should clear the queue', () => { const res: number[] = []; @@ -127,9 +127,9 @@ describe('core/queue/worker/simple', () => { }, {concurrency: 1}); - await queue.unshift({a: 1}); - await queue.unshift({a: 2}); - await queue.unshift({a: 3}); + queue.unshift({a: 1}); + queue.unshift({a: 2}); + queue.unshift({a: 3}); expect(queue.length).toBe(2); diff --git a/src/core/request/spec.ts b/src/core/request/spec.ts index 81581011f..88923e37a 100644 --- a/src/core/request/spec.ts +++ b/src/core/request/spec.ts @@ -284,7 +284,7 @@ describe('core/request', () => { middlewares: { addId({opts}: MiddlewareParams) { - if (Object.isDictionary(opts.body) && 'id' in opts.body) { + if (Object.isDictionary(opts.body)) { opts.body.id = 12345; } }, From 0aa8603b3afce66e85714acd07a6c654b6736ed4 Mon Sep 17 00:00:00 2001 From: kz2d Date: Fri, 14 Oct 2022 12:38:16 +0300 Subject: [PATCH 11/20] second part --- index.d.ts | 6 +- .../base/{clear.spec.js => clear.spec.ts} | 0 .../base/{label.spec.js => label.spec.ts} | 19 +++--- .../base/{mark.spec.js => mark.spec.ts} | 0 src/core/async/modules/events/index.ts | 14 ++--- .../async/modules/events/{spec.js => spec.ts} | 0 .../{iterable.spec.js => iterable.spec.ts} | 0 .../async/modules/timers/{spec.js => spec.ts} | 4 +- .../modules/wrappers/{spec.js => spec.ts} | 2 +- .../helpers/add-emitter/{spec.js => spec.ts} | 0 .../persistent/{spec.js => spec.ts} | 0 .../cache/decorators/{spec.js => spec.ts} | 4 +- .../cache/decorators/ttl/{spec.js => spec.ts} | 9 ++- src/core/cache/never/{spec.js => spec.ts} | 0 .../cache/restricted/{spec.js => spec.ts} | 2 +- src/core/cache/simple/{spec.js => spec.ts} | 2 +- src/core/data/{spec.js => spec.ts} | 60 +++++++++++-------- src/core/iter/combinators/index.ts | 6 +- .../iter/combinators/{spec.js => spec.ts} | 2 +- src/core/iter/index.ts | 4 +- src/core/iter/{spec.js => spec.ts} | 10 ++-- src/core/json/{spec.js => spec.ts} | 0 src/core/kv-storage/{spec.js => spec.ts} | 0 .../prelude/date/create/{spec.js => spec.ts} | 4 +- .../prelude/date/format/{spec.js => spec.ts} | 8 +++ .../function/monad/{spec.js => spec.ts} | 4 +- .../object/iterators/{spec.js => spec.ts} | 12 ++-- src/core/request/error/{spec.js => spec.ts} | 18 +++--- 28 files changed, 109 insertions(+), 81 deletions(-) rename src/core/async/modules/base/{clear.spec.js => clear.spec.ts} (100%) rename src/core/async/modules/base/{label.spec.js => label.spec.ts} (93%) rename src/core/async/modules/base/{mark.spec.js => mark.spec.ts} (100%) rename src/core/async/modules/events/{spec.js => spec.ts} (100%) rename src/core/async/modules/proxy/{iterable.spec.js => iterable.spec.ts} (100%) rename src/core/async/modules/timers/{spec.js => spec.ts} (98%) rename src/core/async/modules/wrappers/{spec.js => spec.ts} (99%) rename src/core/cache/decorators/helpers/add-emitter/{spec.js => spec.ts} (100%) rename src/core/cache/decorators/persistent/{spec.js => spec.ts} (100%) rename src/core/cache/decorators/{spec.js => spec.ts} (91%) rename src/core/cache/decorators/ttl/{spec.js => spec.ts} (96%) rename src/core/cache/never/{spec.js => spec.ts} (100%) rename src/core/cache/restricted/{spec.js => spec.ts} (98%) rename src/core/cache/simple/{spec.js => spec.ts} (97%) rename src/core/data/{spec.js => spec.ts} (65%) rename src/core/iter/combinators/{spec.js => spec.ts} (98%) rename src/core/iter/{spec.js => spec.ts} (92%) rename src/core/json/{spec.js => spec.ts} (100%) rename src/core/kv-storage/{spec.js => spec.ts} (100%) rename src/core/prelude/date/create/{spec.js => spec.ts} (98%) rename src/core/prelude/date/format/{spec.js => spec.ts} (94%) rename src/core/prelude/function/monad/{spec.js => spec.ts} (96%) rename src/core/prelude/object/iterators/{spec.js => spec.ts} (93%) rename src/core/request/error/{spec.js => spec.ts} (91%) diff --git a/index.d.ts b/index.d.ts index 956381cc9..b884f7b59 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3170,7 +3170,7 @@ interface DateConstructor { * @param opts * @param locale */ - format(opts: Intl.NumberFormatOptions, locale?: CanArray): (date: Date) => string; + format(opts: Intl.DateTimeFormatOptions, locale?: CanArray): (date: Date) => string; /** * Returns a string representation of the date by the specified pattern. @@ -3259,7 +3259,7 @@ interface DateConstructor { * Returns a curried version of `Date.toHTMLTimeString` * @param opts - additional options */ - toHTMLTimeString(opts: DateHTMLDateStringOptions): (date: Date) => string; + toHTMLTimeString(opts: DateHTMLTimeStringOptions): (date: Date) => string; /** * Returns an HTML string representation of a timestamp from the date. @@ -3985,7 +3985,7 @@ interface Function { * ``` */ result(this: (a1: A1, ...rest: A) => R): - (a1: Maybe | Either, ...rest: A) => Either; + (a1: Parameters[0] | Maybe | Either, ...rest: A) => Either; /** * Returns a curried equivalent of the function. diff --git a/src/core/async/modules/base/clear.spec.js b/src/core/async/modules/base/clear.spec.ts similarity index 100% rename from src/core/async/modules/base/clear.spec.js rename to src/core/async/modules/base/clear.spec.ts diff --git a/src/core/async/modules/base/label.spec.js b/src/core/async/modules/base/label.spec.ts similarity index 93% rename from src/core/async/modules/base/label.spec.js rename to src/core/async/modules/base/label.spec.ts index b17cb0eba..d5e282715 100644 --- a/src/core/async/modules/base/label.spec.js +++ b/src/core/async/modules/base/label.spec.ts @@ -13,8 +13,11 @@ const $$ = symbolGenerator(); describe('core/async/modules/base `label`', () => { - const onResolve = (res, label) => (v = label) => { - res.push(v); + const onResolve = (res: string[], label?: string) => (v = label) => { + if (v != null) { + res.push(v); + } + return label; }; @@ -42,7 +45,7 @@ describe('core/async/modules/base `label`', () => { const $a = new Async(), spy = jest.fn(), - res = []; + res: string[] = []; $a.promise(Promise.resolve('first'), {label: $$.foo}).then(onResolve(res), onReject(spy)); $a.promise(Promise.resolve('second'), {label: $$.foo}).then(onResolve(res), onReject(spy)); @@ -73,7 +76,7 @@ describe('core/async/modules/base `label`', () => { it('label collision with promises and joining', (done) => { const $a = new Async(), - res = []; + res: string[] = []; $a.promise(Promise.resolve('first'), {label: $$.foo, join: true}) .then(onResolve(res)); @@ -91,7 +94,7 @@ describe('core/async/modules/base `label`', () => { const $a = new Async(), spy = jest.fn(), - res = []; + res: string[] = []; $a.setTimeout(onResolve(res, 'first'), 10, {label: $$.foo, join: 'replace', onClear: onReject(spy)}); $a.setTimeout(onResolve(res, 'second'), 10, {label: $$.foo, join: 'replace', onClear: onReject(spy)}); @@ -107,7 +110,7 @@ describe('core/async/modules/base `label`', () => { const $a = new Async(), spy = jest.fn(), - res = []; + res: string[] = []; $a.promise(Promise.resolve('first'), {label: $$.foo, join: 'replace'}).then(onResolve(res), onReject(spy)); $a.promise(Promise.resolve('second'), {label: $$.foo, join: 'replace'}).then(onResolve(res), onReject(spy)); @@ -121,7 +124,7 @@ describe('core/async/modules/base `label`', () => { it('label collision with iterables and replacing', async () => { const $a = new Async(); - const result = []; + const result: number[] = []; await Promise.all([ (async () => { @@ -149,7 +152,7 @@ describe('core/async/modules/base `label`', () => { it('label collision with iterables and join', async () => { const $a = new Async(); - const result = []; + const result: number[] = []; await Promise.all([ (async () => { diff --git a/src/core/async/modules/base/mark.spec.js b/src/core/async/modules/base/mark.spec.ts similarity index 100% rename from src/core/async/modules/base/mark.spec.js rename to src/core/async/modules/base/mark.spec.ts diff --git a/src/core/async/modules/events/index.ts b/src/core/async/modules/events/index.ts index 20962467a..3a9abbb93 100644 --- a/src/core/async/modules/events/index.ts +++ b/src/core/async/modules/events/index.ts @@ -59,7 +59,7 @@ export default class Async> extends Super { events: CanArray, handler: ProxyCb, ...args: unknown[] - ): Nullable; + ): CanUndef; /** * Attaches an event listener from the specified event emitter. @@ -78,7 +78,7 @@ export default class Async> extends Super { handler: ProxyCb, opts: AsyncOnOptions, ...args: unknown[] - ): Nullable; + ): CanUndef; on( emitter: EventEmitterLikeP, @@ -86,7 +86,7 @@ export default class Async> extends Super { handler: ProxyCb, opts?: AsyncOnOptions | unknown[], ...args: unknown[] - ): Nullable { + ): CanUndef { let p: AsyncOnOptions; @@ -197,7 +197,7 @@ export default class Async> extends Super { } } - return events.length <= 1 ? links[0] ?? null : links; + return events.length <= 1 ? links[0] ?? undefined : links; } /** @@ -215,7 +215,7 @@ export default class Async> extends Super { events: CanArray, handler: ProxyCb, ...args: unknown[] - ): Nullable; + ): CanUndef; /** * Attaches an event listener from the specified event emitter, but the event is listened only once. @@ -234,7 +234,7 @@ export default class Async> extends Super { handler: ProxyCb, opts: AsyncOnceOptions, ...args: unknown[] - ): Nullable; + ): CanUndef; once( emitter: EventEmitterLikeP, @@ -242,7 +242,7 @@ export default class Async> extends Super { handler: ProxyCb, opts?: AsyncOnceOptions | unknown[], ...args: unknown[] - ): Nullable { + ): CanUndef { let p: AsyncOnceOptions; diff --git a/src/core/async/modules/events/spec.js b/src/core/async/modules/events/spec.ts similarity index 100% rename from src/core/async/modules/events/spec.js rename to src/core/async/modules/events/spec.ts diff --git a/src/core/async/modules/proxy/iterable.spec.js b/src/core/async/modules/proxy/iterable.spec.ts similarity index 100% rename from src/core/async/modules/proxy/iterable.spec.js rename to src/core/async/modules/proxy/iterable.spec.ts diff --git a/src/core/async/modules/timers/spec.js b/src/core/async/modules/timers/spec.ts similarity index 98% rename from src/core/async/modules/timers/spec.js rename to src/core/async/modules/timers/spec.ts index 31ab3d46a..540ff7a11 100644 --- a/src/core/async/modules/timers/spec.js +++ b/src/core/async/modules/timers/spec.ts @@ -29,7 +29,7 @@ describe('core/async/modules/timers', () => { clear = clear || `clear-${method}`.camelize(false); const - args = []; + args: number[] = []; if (method === 'timeout' || method === 'interval') { args.push(10); @@ -220,7 +220,7 @@ describe('core/async/modules/timers', () => { it(`\`${method}\``, (done) => { const $a = new Async(), - args = []; + args: Array boolean)> = []; let i = 0; diff --git a/src/core/async/modules/wrappers/spec.js b/src/core/async/modules/wrappers/spec.ts similarity index 99% rename from src/core/async/modules/wrappers/spec.js rename to src/core/async/modules/wrappers/spec.ts index 95652124d..9e4909d88 100644 --- a/src/core/async/modules/wrappers/spec.js +++ b/src/core/async/modules/wrappers/spec.ts @@ -288,7 +288,7 @@ describe('core/async/modules/wrappers', () => { mainMethods.forEach(testMethod); - function testMethod(methodName) { + function testMethod(methodName: string) { describe(`\`${methodName}\``, () => { it('should call the original method and return its result', async () => { const diff --git a/src/core/cache/decorators/helpers/add-emitter/spec.js b/src/core/cache/decorators/helpers/add-emitter/spec.ts similarity index 100% rename from src/core/cache/decorators/helpers/add-emitter/spec.js rename to src/core/cache/decorators/helpers/add-emitter/spec.ts diff --git a/src/core/cache/decorators/persistent/spec.js b/src/core/cache/decorators/persistent/spec.ts similarity index 100% rename from src/core/cache/decorators/persistent/spec.js rename to src/core/cache/decorators/persistent/spec.ts diff --git a/src/core/cache/decorators/spec.js b/src/core/cache/decorators/spec.ts similarity index 91% rename from src/core/cache/decorators/spec.js rename to src/core/cache/decorators/spec.ts index b0d6f1149..e13dba1ab 100644 --- a/src/core/cache/decorators/spec.js +++ b/src/core/cache/decorators/spec.ts @@ -8,7 +8,7 @@ import { asyncLocal } from 'core/kv-storage'; -import addPersistent from 'core/cache/decorators/persistent'; +import addPersistent, {PersistentOptions} from 'core/cache/decorators/persistent'; import addTTL from 'core/cache/decorators/ttl'; import RestrictedCache from 'core/cache/restricted'; @@ -19,7 +19,7 @@ describe('core/cache/decorators', () => { it('complex test', async () => { jest.spyOn(Date, 'now').mockReturnValue(0); - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; diff --git a/src/core/cache/decorators/ttl/spec.js b/src/core/cache/decorators/ttl/spec.ts similarity index 96% rename from src/core/cache/decorators/ttl/spec.js rename to src/core/cache/decorators/ttl/spec.ts index bc5edc5e8..20c504852 100644 --- a/src/core/cache/decorators/ttl/spec.js +++ b/src/core/cache/decorators/ttl/spec.ts @@ -106,10 +106,11 @@ describe('core/cache/decorators/ttl', () => { it('should delete a value from the storage if a side effect has deleted it', () => { const cache = addTTL(new RestrictedCache(1)), - memory = []; + memory: string[] = []; cache.removeTTLFrom = (key) => { memory.push(key); + return true; }; cache.set('bar', 1, {ttl: 1000}); @@ -122,10 +123,11 @@ describe('core/cache/decorators/ttl', () => { const originalCache = new SimpleCache(), cache = addTTL(originalCache), - memory = []; + memory: string[] = []; cache.removeTTLFrom = (key) => { memory.push(key); + return true; }; cache.set('bar', 1, {ttl: 100}); @@ -140,10 +142,11 @@ describe('core/cache/decorators/ttl', () => { const originalCache = new SimpleCache(), cache = addTTL(originalCache), - memory = []; + memory: string[] = []; cache.removeTTLFrom = (key) => { memory.push(key); + return true; }; cache.set('bar', 1, {ttl: 100}); diff --git a/src/core/cache/never/spec.js b/src/core/cache/never/spec.ts similarity index 100% rename from src/core/cache/never/spec.js rename to src/core/cache/never/spec.ts diff --git a/src/core/cache/restricted/spec.js b/src/core/cache/restricted/spec.ts similarity index 98% rename from src/core/cache/restricted/spec.js rename to src/core/cache/restricted/spec.ts index c9f5e1c8c..b9a5ed624 100644 --- a/src/core/cache/restricted/spec.js +++ b/src/core/cache/restricted/spec.ts @@ -97,7 +97,7 @@ describe('core/cache/restricted', () => { }); it('`clear` with a filter', () => { - const cache = new RestrictedCache(); + const cache = new RestrictedCache(); cache.set('foo', 1); cache.set('bar', 2); diff --git a/src/core/cache/simple/spec.js b/src/core/cache/simple/spec.ts similarity index 97% rename from src/core/cache/simple/spec.js rename to src/core/cache/simple/spec.ts index b68232428..43185a893 100644 --- a/src/core/cache/simple/spec.js +++ b/src/core/cache/simple/spec.ts @@ -74,7 +74,7 @@ describe('core/cache/simple', () => { }); it('`clear` with a filter', () => { - const cache = new SimpleCache(); + const cache = new SimpleCache(); cache.set('foo', 1); cache.set('bar', 2); diff --git a/src/core/data/spec.js b/src/core/data/spec.ts similarity index 65% rename from src/core/data/spec.js rename to src/core/data/spec.ts index 5ad2106e8..baf4e4ddb 100644 --- a/src/core/data/spec.js +++ b/src/core/data/spec.ts @@ -9,13 +9,18 @@ /* eslint-disable capitalized-comments,no-tabs */ import express from 'express'; -import Provider, { provider, providers } from 'core/data'; +import Provider, { DecodersMap, EncodersMap, ModelMethod, provider, providers, RequestMethod } from 'core/data'; +import type { Server } from 'http'; + +interface ResponseJson { + message: string; +} describe('core/data', () => { - let server; + let server: CanUndef; beforeEach(() => { - if (server) { + if (server != null) { server.close(); } @@ -23,17 +28,17 @@ describe('core/data', () => { }); afterAll((done) => { - server.close(done); + server?.close(done); }); it('simple provider', async () => { @provider class TestProvider extends Provider { - static request = Provider.request({api: {url: 'http://localhost:3000/'}}); + static override request: typeof Provider.request = Provider.request({api: {url: 'http://localhost:3000/'}}); - baseGetURL = 'json/1'; + override baseGetURL: string = 'json/1'; - baseAddURL = 'json'; + override baseAddURL: string = 'json'; } const @@ -52,12 +57,12 @@ describe('core/data', () => { it('provider with overrides', async () => { @provider class TestOverrideProvider extends Provider { - static request = Provider.request({api: {url: 'http://localhost:3000/'}}); + static override request: typeof Provider.request = Provider.request({api: {url: 'http://localhost:3000/'}}); } const dp = new TestOverrideProvider(), - mdp = dp.name('bla').url('json'); + mdp = dp.name('bla').url('json'); const spy = jest.fn(); mdp.emitter.on('bla', async (getData) => spy('bla', await getData())); @@ -70,42 +75,45 @@ describe('core/data', () => { it('namespaced provider with encoders/decoders', async () => { @provider('foo') - // eslint-disable-next-line no-unused-vars + // eslint-disable-next-line @typescript-eslint/no-unused-vars-experimental class TestNamespacedProvider extends Provider { - static encoders = { + static override encoders: EncodersMap = { upd: [ - (data) => { - data.value = data.value.join('-'); + (data: Dictionary) => { + if (Object.isArray(data.value)) { + data.value = data.value.join('-'); + } + return data; } ] }; - static decoders = { + static override decoders: DecodersMap = { get: [ - (data) => { + (data: Dictionary) => { data.id = String(data.id); return data; } ] }; - baseGetURL = 'http://localhost:3000/json/1'; + override baseGetURL: string = 'http://localhost:3000/json/1'; - updMethod = 'POST'; + override updMethod: RequestMethod = 'POST'; - baseUpdURL = 'http://localhost:3000/json'; + override baseUpdURL: string = 'http://localhost:3000/json'; } const // eslint-disable-next-line new-cap - dp = new providers['foo.TestNamespacedProvider'](); + dp = new providers['foo.TestNamespacedProvider']!(); expect(await dp.get().data) .toEqual({id: '1', value: 'things'}); const spy = jest.fn(); - dp.emitter.on('upd', async (getData) => spy('upd', await getData())); + dp.emitter.on!('upd', async (getData) => spy('upd', await getData())); expect(await dp.upd({id: 12345, value: ['abc', 'def', 'ghi']}).data) .toEqual({message: 'Success'}); @@ -116,16 +124,16 @@ describe('core/data', () => { it('`get` with extra providers', async () => { @provider class TestExtraProvider extends Provider { - baseGetURL = 'http://localhost:3000/json/1'; + override baseGetURL: string = 'http://localhost:3000/json/1'; } @provider class TestProviderWithExtra extends Provider { - alias = 'foo'; + override alias: string = 'foo'; - baseGetURL = 'http://localhost:3000/json/1'; + override baseGetURL: string = 'http://localhost:3000/json/1'; - extraProviders = () => ({ + override extraProviders = () => ({ TestExtraProvider: { alias: 'bla' }, @@ -133,7 +141,7 @@ describe('core/data', () => { bar: { provider: new TestExtraProvider() } - }) + }); } const @@ -147,7 +155,7 @@ describe('core/data', () => { }); }); -function createServer() { +function createServer(): Server { const serverApp = express(); serverApp.use(express.json()); diff --git a/src/core/iter/combinators/index.ts b/src/core/iter/combinators/index.ts index 272687208..5ced405a7 100644 --- a/src/core/iter/combinators/index.ts +++ b/src/core/iter/combinators/index.ts @@ -15,9 +15,9 @@ * Takes iterable objects and returns a new iterator that produces values from them sequentially * @param iterables */ -export function sequence>( - ...iterables: T[] -): IterableIterator>; +export function sequence( + ...iterables: Array> +): IterableIterator; /** * Takes async iterable objects and returns a new async iterator that produces values from them sequentially diff --git a/src/core/iter/combinators/spec.js b/src/core/iter/combinators/spec.ts similarity index 98% rename from src/core/iter/combinators/spec.js rename to src/core/iter/combinators/spec.ts index 0c81c9f7f..6c0ab49ce 100644 --- a/src/core/iter/combinators/spec.js +++ b/src/core/iter/combinators/spec.ts @@ -33,7 +33,7 @@ describe('core/iter/combinators', () => { ); const - res = []; + res: any[] = []; for await (const val of seq) { res.push(val); diff --git a/src/core/iter/index.ts b/src/core/iter/index.ts index 653fdfd2d..81157375d 100644 --- a/src/core/iter/index.ts +++ b/src/core/iter/index.ts @@ -57,13 +57,13 @@ export function intoIter(obj: ArrayLike): IterableIterator; * Creates an iterator from the passed generator function and returns it * @param obj */ -export function intoIter(obj: GeneratorFunction): IterableIterator; +export function intoIter(obj: () => Generator): IterableIterator; /** * Creates an iterator from the passed async generator function and returns it * @param obj */ -export function intoIter(obj: AsyncGeneratorFunction): AsyncIterableIterator; +export function intoIter(obj: () => AsyncGenerator): AsyncIterableIterator; /** * Creates a new iterator based on the specified iterable structure and returns it diff --git a/src/core/iter/spec.js b/src/core/iter/spec.ts similarity index 92% rename from src/core/iter/spec.js rename to src/core/iter/spec.ts index cb749d6db..cad6a540c 100644 --- a/src/core/iter/spec.js +++ b/src/core/iter/spec.ts @@ -13,7 +13,7 @@ describe('core/iter', () => { it('passing `true` as a value', () => { const iter = intoIter(true), - res = []; + res: number[] = []; let i = 0; @@ -33,7 +33,7 @@ describe('core/iter', () => { it('passing `false` as a value', () => { const iter = intoIter(false), - res = []; + res: number[] = []; let i = 0; @@ -94,13 +94,14 @@ describe('core/iter', () => { }); it('passing an async generator as a value', async () => { + // eslint-disable-next-line @typescript-eslint/require-await async function* gen() { yield* [1, 2]; } const iter = intoIter(gen), - res = []; + res: number[] = []; for await (const val of intoIter(gen)) { res.push(val); @@ -125,13 +126,14 @@ describe('core/iter', () => { }); it('passing an async iterable as a value', async () => { + // eslint-disable-next-line @typescript-eslint/require-await async function* gen() { yield* [1, 2]; } const iter = intoIter(gen()), - res = []; + res: number[] = []; for await (const val of intoIter(gen)) { res.push(val); diff --git a/src/core/json/spec.js b/src/core/json/spec.ts similarity index 100% rename from src/core/json/spec.js rename to src/core/json/spec.ts diff --git a/src/core/kv-storage/spec.js b/src/core/kv-storage/spec.ts similarity index 100% rename from src/core/kv-storage/spec.js rename to src/core/kv-storage/spec.ts diff --git a/src/core/prelude/date/create/spec.js b/src/core/prelude/date/create/spec.ts similarity index 98% rename from src/core/prelude/date/create/spec.js rename to src/core/prelude/date/create/spec.ts index 7c63850e6..4921938fa 100644 --- a/src/core/prelude/date/create/spec.js +++ b/src/core/prelude/date/create/spec.ts @@ -17,7 +17,7 @@ describe('core/prelude/date/create', () => { expect(Date.create().is(date, 10e3)).toBe(true); for (let v = [null, undefined, ''], i = 0; i < v.length; i++) { - expect(Date.create(v[i]).is(date, 10e3)).toBe(true); + expect(Date.create(v[i]).is(date, 10e3)).toBe(true); } }); @@ -53,6 +53,8 @@ describe('core/prelude/date/create', () => { today.getDate().toString().padStart(2, 0) ]; + console.warn(chunks); + expect(Date.create(chunks.join('.'))).toEqual(today); expect(Date.create(chunks.slice().reverse().join('.'))).toEqual(today); diff --git a/src/core/prelude/date/format/spec.js b/src/core/prelude/date/format/spec.ts similarity index 94% rename from src/core/prelude/date/format/spec.js rename to src/core/prelude/date/format/spec.ts index 3b70a1d6c..8336e8f7c 100644 --- a/src/core/prelude/date/format/spec.js +++ b/src/core/prelude/date/format/spec.ts @@ -25,6 +25,14 @@ describe('core/prelude/date/format', () => { expect(Date.medium('en')(date)).toBe('October 18, 1989'); }); + it('`long`', () => { + expect(date.long('en')).toBe('October 18, 1989, 10:10:10 AM'); + }); + + it('`Date.long`', () => { + expect(Date.long('en')(date)).toBe('October 18, 1989, 10:10:10 AM'); + }); + it('`format`', () => { expect(date.format('Y;M:2-digit', 'en')).toBe('10/1989'); expect(date.format({year: 'numeric'})).toBe('1989'); diff --git a/src/core/prelude/function/monad/spec.js b/src/core/prelude/function/monad/spec.ts similarity index 96% rename from src/core/prelude/function/monad/spec.js rename to src/core/prelude/function/monad/spec.ts index 727210f51..7296306c5 100644 --- a/src/core/prelude/function/monad/spec.js +++ b/src/core/prelude/function/monad/spec.ts @@ -9,7 +9,7 @@ describe('core/prelude/function/monad', () => { it('`option`', async () => { const - square = ((n) => n * n).option(); + square = ((n: number) => n * n).option(); expect(await square(2)).toBe(4); expect(await square(square(2))).toBe(16); @@ -38,7 +38,7 @@ describe('core/prelude/function/monad', () => { it('`result`', async () => { const - square = (n) => n * n, + square = (n: number) => n * n, call = ((f, ...args) => f(...args)).result(), read = ((v) => v).result(); diff --git a/src/core/prelude/object/iterators/spec.js b/src/core/prelude/object/iterators/spec.ts similarity index 93% rename from src/core/prelude/object/iterators/spec.js rename to src/core/prelude/object/iterators/spec.ts index 403231690..6193b7d3f 100644 --- a/src/core/prelude/object/iterators/spec.js +++ b/src/core/prelude/object/iterators/spec.ts @@ -10,7 +10,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an array', () => { const data = [1, 2, 3], - scan = []; + scan: Array<[number, number, number[]]> = []; Object.forEach(data, (...args) => { scan.push(args); @@ -26,7 +26,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of a string', () => { const data = 'foo', - scan = []; + scan: Array<[string, null, Iterable]> = []; Object.forEach(data, (...args) => { scan.push(args); @@ -57,7 +57,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of a Map', () => { const data = new Map([[0, 1], [1, 2], [2, 3]]), - scan = []; + scan: Array<[number, number, Map]> = []; Object.forEach(data, (...args) => { scan.push(args); @@ -73,7 +73,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of a Set', () => { const data = new Set([1, 2, 3]), - scan = []; + scan: Array<[number, number, Set]> = []; Object.forEach(data, (...args) => { scan.push(args); @@ -89,7 +89,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an iterator', () => { const data = [1, 2, 3].values(), - scan = []; + scan: Array<[number, null, Iterable]> = []; Object.forEach(data, (...args) => { scan.push(args); @@ -105,7 +105,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an object', () => { const data = {a: 1, b: 2, __proto__: {c: 3}}, - scan = []; + scan: Array<[number, string, Dictionary]> = []; Object.forEach(data, (...args) => { scan.push(args); diff --git a/src/core/request/error/spec.js b/src/core/request/error/spec.ts similarity index 91% rename from src/core/request/error/spec.js rename to src/core/request/error/spec.ts index bda29b37d..3081ebb36 100644 --- a/src/core/request/error/spec.js +++ b/src/core/request/error/spec.ts @@ -8,16 +8,17 @@ * https://github.com/V4Fire/Core/blob/master/LICENSE */ -import RequestError from 'core/request/error'; +import RequestError, { RequestErrorDetailsExtractor } from 'core/request/error'; import V4Headers from 'core/request/headers'; -import { RequestErrorDetailsExtractor } from 'core/request/error'; - describe('core/request/error', () => { let err; beforeEach(() => { + // TODO err = new RequestError(RequestError.Timeout, { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore request: { url: 'url/url', @@ -28,21 +29,22 @@ describe('core/request/error', () => { contentType: 'application/json; charset=utf-8', credentials: false, - headers: { + headers: new V4Headers({ content: 'json', token: 'important token', foo: 'bla' - } + }) }, - + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore response: { status: 404, body: 'not found', - headers: { + headers: new V4Headers({ content: 'xml', token: 'other token', foo: 'bla' - } + }) } }); }); From ee8287505fdf68f7c997a6a3a6b06b87d70ab151 Mon Sep 17 00:00:00 2001 From: kobezzza Date: Mon, 12 Sep 2022 17:51:46 +0300 Subject: [PATCH 12/20] feat: now `push` and `unshift` methods support multiple arguments --- CHANGELOG.md | 6 ++++ src/core/linked-list/CHANGELOG.md | 6 ++++ src/core/linked-list/README.md | 11 +++---- src/core/linked-list/list.ts | 51 ++++++++++++++++++------------- 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a5014457..f36021f95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ Changelog _Note: Gaps between patch versions are faulty, broken or test releases._ +## v3.??.?? (2022-??-??) + +#### :rocket: New Feature + +* Now `push` and `unshift` methods support multiple arguments `core/linked-list` + ## v3.88.0 (2022-08-22) #### :rocket: New Feature diff --git a/src/core/linked-list/CHANGELOG.md b/src/core/linked-list/CHANGELOG.md index ac50537d8..9f353e9b3 100644 --- a/src/core/linked-list/CHANGELOG.md +++ b/src/core/linked-list/CHANGELOG.md @@ -9,6 +9,12 @@ Changelog > - :house: [Internal] > - :nail_care: [Polish] +## v3.??.?? (2022-??-??) + +#### :rocket: New Feature + +* Now `push` and `unshift` methods support multiple arguments + ## v3.88.0 (2022-08-22) #### :rocket: New Feature diff --git a/src/core/linked-list/README.md b/src/core/linked-list/README.md index a9b2b2ef7..761ccb1c5 100644 --- a/src/core/linked-list/README.md +++ b/src/core/linked-list/README.md @@ -9,8 +9,7 @@ import LinkedList from 'core/linked-list'; const list = new LinkedList(); -list.push(10); -list.push(11); +list.push(10, 11); // 2 console.log(list.length); @@ -109,8 +108,7 @@ For convenience, the LinkedList API is similar to the regular JS Array API: const list = new LinkedList(); - list.push(10); - list.push(11); + list.push(10, 11); list.unshift(9); // 11 @@ -142,9 +140,8 @@ For convenience, the LinkedList API is similar to the regular JS Array API: const list = new LinkedList(); - list.push(10); // 1 - list.push(11); // 2 - list.unshift(9); // 3 + list.push(10, 11); // 2 + list.unshift(9); // 3 // 3 console.log(list.length); diff --git a/src/core/linked-list/list.ts b/src/core/linked-list/list.ts index 14fb9e76f..247756f7a 100644 --- a/src/core/linked-list/list.ts +++ b/src/core/linked-list/list.ts @@ -71,21 +71,24 @@ export default class List { * Adds the passed data to the beginning of the list and returns its new length * @param data */ - unshift(data: T): number { - const - link = new Node(data); + unshift(...data: T[]): number { + data.forEach((data) => { + const + link = new Node(data); - if (this.firstNode != null) { - this.firstNode.prev = link; + if (this.firstNode != null) { + this.firstNode.prev = link; - } else { - this.lastNode = link; - } + } else { + this.lastNode = link; + } - link.next = this.firstNode; - this.firstNode = link; + link.next = this.firstNode; + this.firstNode = link; + this.lengthStore++; + }); - return ++this.lengthStore; + return this.lengthStore; } /** @@ -121,20 +124,24 @@ export default class List { * Adds the passed data to the end of the list and returns its new length * @param data */ - push(data: T): number { - const - link = new Node(data); + push(...data: T[]): number { + data.forEach((data) => { + const + link = new Node(data); - if (this.lastNode == null) { - this.firstNode = link; + if (this.lastNode == null) { + this.firstNode = link; - } else { - this.lastNode.next = link; - link.prev = this.lastNode; - } + } else { + this.lastNode.next = link; + link.prev = this.lastNode; + } + + this.lastNode = link; + this.lengthStore++; + }); - this.lastNode = link; - return ++this.lengthStore; + return this.lengthStore; } /** From f9b777dc1fa13157d270669b4af609009e8709bd Mon Sep 17 00:00:00 2001 From: kholstinin Date: Thu, 15 Sep 2022 16:29:54 +0500 Subject: [PATCH 13/20] fix: rollback ES in dev mode --- CHANGELOG.md | 6 +++++- config/CHANGELOG.md | 6 ++++++ config/default.js | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f36021f95..3f4174c31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,16 @@ Changelog _Note: Gaps between patch versions are faulty, broken or test releases._ -## v3.??.?? (2022-??-??) +## v3.89.0 (2022-09-15) #### :rocket: New Feature * Now `push` and `unshift` methods support multiple arguments `core/linked-list` +#### :boom: Breaking Change + +* By default, the `ES` flag is set to `ES2019` for development builds `config` + ## v3.88.0 (2022-08-22) #### :rocket: New Feature diff --git a/config/CHANGELOG.md b/config/CHANGELOG.md index 703772e9b..0208e167b 100644 --- a/config/CHANGELOG.md +++ b/config/CHANGELOG.md @@ -9,6 +9,12 @@ Changelog > - :house: [Internal] > - :nail_care: [Polish] +## v3.89.0 (2022-09-15) + +#### :boom: Breaking Change + +* By default, the `ES` flag is set to `ES2019` for development builds + ## v3.87.1 (2022-08-15) #### :boom: Breaking Change diff --git a/config/default.js b/config/default.js index 8f0da57d6..51b2718fe 100644 --- a/config/default.js +++ b/config/default.js @@ -399,7 +399,7 @@ module.exports = config.createConfig( es() { return o('es', { env: true, - default: isProd ? 'ES6' : 'ES2021', + default: isProd ? 'ES6' : 'ES2019', coerce(value) { return value.toUpperCase(); } diff --git a/package-lock.json b/package-lock.json index 83dceb366..754e4dba1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@v4fire/core", - "version": "3.88.0", + "version": "3.89.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@v4fire/core", - "version": "3.88.0", + "version": "3.89.0", "license": "MIT", "dependencies": { "@swc/core": "1.2.153", diff --git a/package.json b/package.json index 8ddddcf7b..f9dbb0732 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/core/index.js", "typings": "index.d.ts", "license": "MIT", - "version": "3.88.0", + "version": "3.89.0", "author": "kobezzza (https://github.com/kobezzza)", "repository": { "type": "git", From f9ea7ba6afa216fff8a740d51e6df634ec8232e8 Mon Sep 17 00:00:00 2001 From: kz2d <56164149+kz2d@users.noreply.github.com> Date: Thu, 13 Oct 2022 15:04:31 +0300 Subject: [PATCH 14/20] fix: date long (#329) Co-authored-by: kz2d --- src/core/prelude/date/format/spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/prelude/date/format/spec.ts b/src/core/prelude/date/format/spec.ts index 8336e8f7c..a763bbf87 100644 --- a/src/core/prelude/date/format/spec.ts +++ b/src/core/prelude/date/format/spec.ts @@ -26,11 +26,11 @@ describe('core/prelude/date/format', () => { }); it('`long`', () => { - expect(date.long('en')).toBe('October 18, 1989, 10:10:10 AM'); + expect(date.long('en')).toBe('October 18, 1989 at 10:10:10 AM'); }); it('`Date.long`', () => { - expect(Date.long('en')(date)).toBe('October 18, 1989, 10:10:10 AM'); + expect(Date.long('en')(date)).toBe('October 18, 1989 at 10:10:10 AM'); }); it('`format`', () => { From 1c4453931b60eb3c0ab89297e4b8021eee4c5887 Mon Sep 17 00:00:00 2001 From: kz2d Date: Fri, 14 Oct 2022 20:43:02 +0300 Subject: [PATCH 15/20] boom: all done, without watch and cache --- .tsconfig | 3 +- index.d.ts | 30 ++++++++- src/core/async/modules/proxy/iterable.spec.ts | 2 +- .../{promise.spec.js => promise.spec.ts} | 0 .../proxy/{proxy.spec.js => proxy.spec.ts} | 0 .../proxy/{worker.spec.js => worker.spec.ts} | 0 src/core/async/modules/wrappers/spec.ts | 37 ++++++----- .../decorators/helpers/add-emitter/spec.ts | 14 ++-- src/core/cache/decorators/persistent/spec.ts | 56 ++++++++-------- .../stream/assembler/{spec.js => spec.ts} | 0 .../json/stream/filters/{spec.js => spec.ts} | 18 ++--- .../json/stream/parser/{spec.js => spec.ts} | 38 +++++------ src/core/json/stream/{spec.js => spec.ts} | 18 ++--- .../stream/streamers/{spec.js => spec.ts} | 0 src/core/kv-storage/interface.ts | 2 +- src/core/lazy/{spec.js => spec.ts} | 65 +++++++++++-------- src/core/linked-list/{spec.js => spec.ts} | 0 .../errors-deduplicator/{spec.js => spec.ts} | 32 ++++----- .../extractor/{spec.js => spec.ts} | 43 ++++++------ src/core/log/middlewares/extractor/testing.ts | 2 +- src/core/mime-type/{spec.js => spec.ts} | 0 src/core/net/{spec.js => spec.ts} | 0 .../object/proxy-clone/{spec.js => spec.ts} | 60 +++++++++-------- .../proxy-readonly/{spec.js => spec.ts} | 50 ++++++++------ src/core/object/select/{spec.js => spec.ts} | 2 +- src/core/object/watch/index.ts | 30 +++++++++ src/core/perf/config/index.ts | 6 +- src/core/perf/config/interface.ts | 2 +- src/core/perf/config/{spec.js => spec.ts} | 0 .../perf/timer/engines/{spec.js => spec.ts} | 0 src/core/perf/timer/impl/{spec.js => spec.ts} | 6 +- src/core/perf/timer/{spec.js => spec.ts} | 10 ++- src/core/pool/{spec.js => spec.ts} | 50 +++++++------- src/core/prelude/date/create/spec.ts | 6 +- src/core/prelude/function/monad/spec.ts | 4 +- src/core/prelude/object/iterators/spec.ts | 38 +++++------ 36 files changed, 356 insertions(+), 268 deletions(-) rename src/core/async/modules/proxy/{promise.spec.js => promise.spec.ts} (100%) rename src/core/async/modules/proxy/{proxy.spec.js => proxy.spec.ts} (100%) rename src/core/async/modules/proxy/{worker.spec.js => worker.spec.ts} (100%) rename src/core/json/stream/assembler/{spec.js => spec.ts} (100%) rename src/core/json/stream/filters/{spec.js => spec.ts} (92%) rename src/core/json/stream/parser/{spec.js => spec.ts} (95%) rename src/core/json/stream/{spec.js => spec.ts} (93%) rename src/core/json/stream/streamers/{spec.js => spec.ts} (100%) rename src/core/lazy/{spec.js => spec.ts} (75%) rename src/core/linked-list/{spec.js => spec.ts} (100%) rename src/core/log/middlewares/errors-deduplicator/{spec.js => spec.ts} (88%) rename src/core/log/middlewares/extractor/{spec.js => spec.ts} (86%) rename src/core/mime-type/{spec.js => spec.ts} (100%) rename src/core/net/{spec.js => spec.ts} (100%) rename src/core/object/proxy-clone/{spec.js => spec.ts} (76%) rename src/core/object/proxy-readonly/{spec.js => spec.ts} (76%) rename src/core/object/select/{spec.js => spec.ts} (98%) rename src/core/perf/config/{spec.js => spec.ts} (100%) rename src/core/perf/timer/engines/{spec.js => spec.ts} (100%) rename src/core/perf/timer/impl/{spec.js => spec.ts} (98%) rename src/core/perf/timer/{spec.js => spec.ts} (97%) rename src/core/pool/{spec.js => spec.ts} (94%) diff --git a/.tsconfig b/.tsconfig index 6ed3abb6d..653d7882b 100644 --- a/.tsconfig +++ b/.tsconfig @@ -22,7 +22,6 @@ "exclude": [ "dist", "config", - "node_modules", - "**/*.spec.ts" + "node_modules" ] } diff --git a/index.d.ts b/index.d.ts index b884f7b59..43f70e8f2 100644 --- a/index.d.ts +++ b/index.d.ts @@ -971,6 +971,32 @@ interface ObjectConstructor { opts?: ObjectForEachOptions ): void; + /** + * Iterates over the specified string + * + * @param obj - string + * @param cb - callback function that is called on each symbol in string + * @param [opts] - additional options + */ + forEach( + obj: string, + cb: (el: string, i: number, data: string) => any, + opts?: ObjectForEachOptions + ): void; + + /** + * Iterates over the specified string + * + * @param obj - string + * @param opts - additional options + * @param cb - callback function that is called on each symbol in string + */ + forEach( + obj: string, + opts: ObjectForEachOptions, + cb: (el: string, key: number, data: string) => any + ): void; + /** * Iterates over the specified iterable object * @@ -1700,7 +1726,7 @@ interface ObjectConstructor { * ``` */ Result(value: (a1: A1, ...a: A) => R): - (a1: Maybe | Either, ...rest: A) => Either; + (a1: A1 | Maybe | Either, ...rest: A) => Either; /** * Wraps the specified value into the Either structure @@ -3985,7 +4011,7 @@ interface Function { * ``` */ result(this: (a1: A1, ...rest: A) => R): - (a1: Parameters[0] | Maybe | Either, ...rest: A) => Either; + (a1: A1 | Maybe | Either, ...rest: A) => Either; /** * Returns a curried equivalent of the function. diff --git a/src/core/async/modules/proxy/iterable.spec.ts b/src/core/async/modules/proxy/iterable.spec.ts index 626440856..9a52f50e8 100644 --- a/src/core/async/modules/proxy/iterable.spec.ts +++ b/src/core/async/modules/proxy/iterable.spec.ts @@ -124,7 +124,7 @@ describe('core/async/modules/proxy `iterable`', () => { }); }); -function expectToBePending(promise) { +function expectToBePending(promise: PromiseLike) { const want = {}; return SyncPromise.race([promise, SyncPromise.resolve(want)]) diff --git a/src/core/async/modules/proxy/promise.spec.js b/src/core/async/modules/proxy/promise.spec.ts similarity index 100% rename from src/core/async/modules/proxy/promise.spec.js rename to src/core/async/modules/proxy/promise.spec.ts diff --git a/src/core/async/modules/proxy/proxy.spec.js b/src/core/async/modules/proxy/proxy.spec.ts similarity index 100% rename from src/core/async/modules/proxy/proxy.spec.js rename to src/core/async/modules/proxy/proxy.spec.ts diff --git a/src/core/async/modules/proxy/worker.spec.js b/src/core/async/modules/proxy/worker.spec.ts similarity index 100% rename from src/core/async/modules/proxy/worker.spec.js rename to src/core/async/modules/proxy/worker.spec.ts diff --git a/src/core/async/modules/wrappers/spec.ts b/src/core/async/modules/wrappers/spec.ts index 9e4909d88..36d6231be 100644 --- a/src/core/async/modules/wrappers/spec.ts +++ b/src/core/async/modules/wrappers/spec.ts @@ -10,7 +10,7 @@ import express from 'express'; -import Async from 'core/async'; +import Async, { EventEmitterLike } from 'core/async'; import Provider, { provider } from 'core/data'; import EventEmitter from 'events'; @@ -27,7 +27,7 @@ describe('core/async/modules/wrappers', () => { @provider class ProviderExample extends Provider { - baseURL = 'http://localhost:3000/ok'; + override baseURL: string = 'http://localhost:3000/ok'; } describe('`wrapDataProvider`', () => { @@ -69,7 +69,7 @@ describe('core/async/modules/wrappers', () => { jest.spyOn($a, 'request'); wrappedProvider.get({id: 1}); - expect($a.request.mock.lastCall[1]).toEqual({group: 'ProviderExample'}); + expect(($a.request).mock.lastCall[1]).toEqual({group: 'ProviderExample'}); }); it('should concatenate a global group and local group', async () => { @@ -80,10 +80,10 @@ describe('core/async/modules/wrappers', () => { jest.spyOn($a, 'request'); await wrappedProvider.get({id: 1}); - expect($a.request.mock.lastCall[1]).toEqual({group: 'example'}); + expect(($a.request).mock.lastCall[1]).toEqual({group: 'example'}); await wrappedProvider.upd({id: 1}, {group: 'foo'}); - expect($a.request.mock.lastCall[1]).toEqual({group: 'example:foo'}); + expect(($a.request).mock.lastCall[1]).toEqual({group: 'example:foo'}); }); it('should provide a group into a nested event emitter wrapper and replace the original emitter with a wrapper', () => { @@ -97,7 +97,7 @@ describe('core/async/modules/wrappers', () => { const wrappedProvider = $a.wrapDataProvider(provider, {group: 'example'}); - expect($a.wrapEventEmitter.mock.lastCall).toEqual([provider.emitter, {group: 'example'}]); + expect(($a.wrapEventEmitter).mock.lastCall).toEqual([provider.emitter, {group: 'example'}]); expect(wrappedProvider.emitter).toEqual(fakeWrapper); }); }); @@ -112,10 +112,10 @@ describe('core/async/modules/wrappers', () => { bar: 'bar' }; - const emitter = $a.wrapEventEmitter(fakeEventEmitter); + const emitter = $a.wrapEventEmitter(fakeEventEmitter); - expect(emitter.foo).toEqual(fakeEventEmitter.foo); - expect(emitter.bar).toEqual(fakeEventEmitter.bar); + expect(emitter['foo']).toEqual(fakeEventEmitter.foo); + expect(emitter['bar']).toEqual(fakeEventEmitter.bar); }); it('`addEventListener` and `addListener` should be aliases for `on`', () => { @@ -145,10 +145,10 @@ describe('core/async/modules/wrappers', () => { group: 'example2' }); - expect($a.on.mock.lastCall[3]).toEqual({group: 'example:example2'}); + expect(($a.on).mock.lastCall[3]).toEqual({group: 'example:example2'}); emitterWithGroup.on('bar', () => null); - expect($a.on.mock.lastCall[3]).toEqual({group: 'example'}); + expect(($a.on).mock.lastCall[3]).toEqual({group: 'example'}); const emitterWithoutGroup = $a.wrapEventEmitter({ on: () => null @@ -158,10 +158,10 @@ describe('core/async/modules/wrappers', () => { group: 'example3' }); - expect($a.on.mock.lastCall[3]).toEqual({group: 'example3'}); + expect(($a.on).mock.lastCall[3]).toEqual({group: 'example3'}); emitterWithoutGroup.on('bar', () => null); - expect($a.on.mock.lastCall[3]).toEqual({}); + expect(($a.on).mock.lastCall[3]).toEqual({}); }); it('normalizes of input parameters', () => { @@ -173,11 +173,11 @@ describe('core/async/modules/wrappers', () => { // [] => [{}] emitter.on('foo', () => null); - expect($a.on.mock.lastCall.slice(3)).toEqual([{}]); + expect(($a.on).mock.lastCall.slice(3)).toEqual([{}]); // [true] => [{}, true] emitter.on('foo', () => null, true); - expect($a.on.mock.lastCall.slice(3)).toEqual([{}, true]); + expect(($a.on).mock.lastCall.slice(3)).toEqual([{}, true]); /* * [{foo: 'foo', group: 'group', label: 'label'}, null, 5] @@ -185,7 +185,7 @@ describe('core/async/modules/wrappers', () => { * [{group: 'group', label: 'label'}, {foo: 'foo'}, null, 5] */ emitter.on('foo', () => null, {foo: 'foo', group: 'group', label: 'label'}, null, 5); - expect($a.on.mock.lastCall.slice(3)).toEqual([{group: 'group', label: 'label'}, {foo: 'foo'}, null, 5]); + expect(($a.on).mock.lastCall.slice(3)).toEqual([{group: 'group', label: 'label'}, {foo: 'foo'}, null, 5]); }); it('`off`, `once`, `promisifyOnce` should call async wrappers', () => { @@ -223,9 +223,14 @@ describe('core/async/modules/wrappers', () => { removeListener: () => originalMethods.removeListener = true }); + /* eslint-disable @typescript-eslint/ban-ts-comment */ + // @ts-ignore emitter.off(null); + // @ts-ignore emitter.removeEventListener('foo'); + // @ts-ignore emitter.removeListener({}, () => null, 'bar', 1); + /* eslint-enable @typescript-eslint/ban-ts-comment */ expect(originalMethods).toEqual({ off: true, diff --git a/src/core/cache/decorators/helpers/add-emitter/spec.ts b/src/core/cache/decorators/helpers/add-emitter/spec.ts index 01feff1f0..651b85019 100644 --- a/src/core/cache/decorators/helpers/add-emitter/spec.ts +++ b/src/core/cache/decorators/helpers/add-emitter/spec.ts @@ -14,7 +14,7 @@ import RestrictedCache from 'core/cache/restricted'; describe('core/cache/decorators/helpers/add-emitter', () => { describe('subscribe', () => { it('emits events only to top', () => { - function CreateLevel(level) { + function CreateLevel(level: number) { this.level = level; this.remove = () => null; this.set = () => null; @@ -26,7 +26,7 @@ describe('core/cache/decorators/helpers/add-emitter', () => { level2 = new CreateLevel(2), level3 = new CreateLevel(3); - const memory = []; + const memory: string[] = []; Object.setPrototypeOf(level2, level1); Object.setPrototypeOf(level3, level2); @@ -54,7 +54,7 @@ describe('core/cache/decorators/helpers/add-emitter', () => { cache = new SimpleCache(), {remove} = addEmitter(cache); - const memory = []; + const memory: any[] = []; cache[eventEmitter].on('remove', (...args) => { memory.push(args); @@ -73,7 +73,7 @@ describe('core/cache/decorators/helpers/add-emitter', () => { const cache = new RestrictedCache(1); addEmitter(cache); - const memory = []; + const memory: any[] = []; cache[eventEmitter].on('remove', (...args) => { memory.push(args); @@ -91,7 +91,7 @@ describe('core/cache/decorators/helpers/add-emitter', () => { cache = new SimpleCache(), {clear} = addEmitter(cache); - const memory = []; + const memory: any[] = []; cache[eventEmitter].on('clear', (...args) => { memory.push(args); @@ -114,7 +114,7 @@ describe('core/cache/decorators/helpers/add-emitter', () => { addEmitter(cache); const - memory = [], + memory: any[] = [], clearFunction = (el, key) => key === 'bar'; cache[eventEmitter].on('clear', (...args) => { @@ -134,7 +134,7 @@ describe('core/cache/decorators/helpers/add-emitter', () => { cache = new SimpleCache(), {set} = addEmitter(cache); - const memory = []; + const memory: any[] = []; cache[eventEmitter].on('set', (...args) => { memory.push(args); diff --git a/src/core/cache/decorators/persistent/spec.ts b/src/core/cache/decorators/persistent/spec.ts index ae5dd1037..0ec70be5a 100644 --- a/src/core/cache/decorators/persistent/spec.ts +++ b/src/core/cache/decorators/persistent/spec.ts @@ -9,7 +9,7 @@ import * as netModule from 'core/net'; import { asyncLocal } from 'core/kv-storage'; -import addPersistent from 'core/cache/decorators/persistent'; +import addPersistent, { PersistentOptions } from 'core/cache/decorators/persistent'; import SimpleCache from 'core/cache/simple'; import RestrictedCache from 'core/cache/restricted'; @@ -28,7 +28,7 @@ describe('core/cache/decorators/persistent', () => { describe('core functionality', () => { it('providing the default `persistentTTL` option', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit', persistentTTL: 100 }; @@ -45,7 +45,7 @@ describe('core/cache/decorators/persistent', () => { }); it('collapsing operations with the same key', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; @@ -57,11 +57,11 @@ describe('core/cache/decorators/persistent', () => { persistentCache.set('foo', 1); await persistentCache.set('foo', 2); - expect(asyncLocal.set.mock.calls[0]).toEqual(['foo', 2]); + expect((asyncLocal.set).mock.calls[0]).toEqual(['foo', 2]); }); it('should delete a value from the storage if a side effect has deleted it', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; @@ -81,7 +81,7 @@ describe('core/cache/decorators/persistent', () => { }); it('`clear` caused by a side effect', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; @@ -101,7 +101,7 @@ describe('core/cache/decorators/persistent', () => { }); it('`set` caused by a side effect', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; @@ -121,7 +121,7 @@ describe('core/cache/decorators/persistent', () => { }); it('setting the default `ttl` caused by a side effect', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit', persistentTTL: 100 }; @@ -140,12 +140,12 @@ describe('core/cache/decorators/persistent', () => { describe('`onInit` loading from the storage', () => { it('should init the cache during initialization', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar'); await persistentCache.set('foo2', 'bar2'); @@ -160,12 +160,12 @@ describe('core/cache/decorators/persistent', () => { }); it('should save the `persistentTTL` descriptor', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar'); await persistentCache.set('foo2', 'bar2', {persistentTTL: 100}); @@ -177,12 +177,12 @@ describe('core/cache/decorators/persistent', () => { }); it('should not save an item if it is already expired', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar', {persistentTTL: -100}); @@ -201,12 +201,12 @@ describe('core/cache/decorators/persistent', () => { }); it('removing the `persistentTTL` descriptor from a cache item', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onInit' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar', {persistentTTL: 100}); @@ -223,9 +223,9 @@ describe('core/cache/decorators/persistent', () => { const fn = jest.fn(); const {onDemand} = engines; - engines.onDemand = function onDemand() { + engines.onDemand = Object.cast(function onDemand() { fn(); - }; + }); await addPersistent(new SimpleCache(), asyncLocal); @@ -236,12 +236,12 @@ describe('core/cache/decorators/persistent', () => { }); it('must save an item at the first demand', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onDemand' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar'); @@ -257,12 +257,12 @@ describe('core/cache/decorators/persistent', () => { }); it('should save the `persistentTTL` descriptor', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onDemand' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar'); await persistentCache.set('foo2', 'bar2', {persistentTTL: 100}); @@ -272,12 +272,12 @@ describe('core/cache/decorators/persistent', () => { }); it('should not save an item if it is already expired', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onDemand' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar', {persistentTTL: -100}); @@ -294,12 +294,12 @@ describe('core/cache/decorators/persistent', () => { }); it('removing the `persistentTTL` descriptor from a cache item', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onDemand' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar', {persistentTTL: 100}); @@ -313,12 +313,12 @@ describe('core/cache/decorators/persistent', () => { describe('`onOfflineDemand` loading from the storage', () => { it('must load a value from the storage cache only if there is no internet', async () => { - const opts = { + const opts: PersistentOptions = { loadFromStorage: 'onOfflineDemand' }; const - persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); + persistentCache = await addPersistent(new SimpleCache(), asyncLocal, opts); await persistentCache.set('foo', 'bar'); await persistentCache.set('foo2', 'bar2'); diff --git a/src/core/json/stream/assembler/spec.js b/src/core/json/stream/assembler/spec.ts similarity index 100% rename from src/core/json/stream/assembler/spec.js rename to src/core/json/stream/assembler/spec.ts diff --git a/src/core/json/stream/filters/spec.js b/src/core/json/stream/filters/spec.ts similarity index 92% rename from src/core/json/stream/filters/spec.js rename to src/core/json/stream/filters/spec.ts index 7b5cc5c8a..036c93a39 100644 --- a/src/core/json/stream/filters/spec.js +++ b/src/core/json/stream/filters/spec.ts @@ -6,7 +6,7 @@ * https://github.com/V4Fire/Core/blob/master/LICENSE */ -import Parser from 'core/json/stream/parser'; +import Parser, { Token } from 'core/json/stream/parser'; import { Filter, Pick } from 'core/json/stream/filters'; describe('core/json/stream/filters', () => { @@ -21,7 +21,7 @@ describe('core/json/stream/filters', () => { }`; const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from([input], new Filter('a.b'))) { tokens.push(token); @@ -41,7 +41,7 @@ describe('core/json/stream/filters', () => { it('filtering tokens by the specified RegExp', async () => { const input = '[{"a": 1}, [1], true, null]', - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from([input], new Filter(/^[02]\.?/))) { tokens.push(token); @@ -53,7 +53,7 @@ describe('core/json/stream/filters', () => { it('filtering tokens by the specified function', async () => { const input = '[{"a": 1}, [1], true, {"a": 2}]', - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from([input], new Filter((stack) => stack.includes('a')))) { tokens.push(token); @@ -74,7 +74,7 @@ describe('core/json/stream/filters', () => { }`; const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from([input], new Pick('a.b'))) { tokens.push(Object.reject(token, 'filterComplete')); @@ -86,7 +86,7 @@ describe('core/json/stream/filters', () => { it('picking the first token matched with the specified RegExp', async () => { const input = '[{"a": 1}, [1], true, null]', - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from([input], new Pick(/^[02]\.?/))) { tokens.push(Object.reject(token, 'filterComplete')); @@ -98,7 +98,7 @@ describe('core/json/stream/filters', () => { it('picking all tokens matched with the specified RegExp', async () => { const input = '[{"a": 1}, [1], true, null]', - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from([input], new Pick(/^[02]\.?/, {multiple: true}))) { tokens.push(Object.reject(token, 'filterComplete')); @@ -113,7 +113,7 @@ describe('core/json/stream/filters', () => { it('picking the first token filtered by the specified function', async () => { const input = '[{"a": 1}, [1], true, {"a": 2}]', - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from([input], new Pick((stack) => stack.includes('a')))) { tokens.push(Object.reject(token, 'filterComplete')); @@ -126,7 +126,7 @@ describe('core/json/stream/filters', () => { it('picking all tokens filtered by the specified function', async () => { const input = '[{"a": 1}, [1], true, {"a": 2}]', - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from([input], new Pick((stack) => stack.includes('a'), {multiple: true}))) { tokens.push(Object.reject(token, 'filterComplete')); diff --git a/src/core/json/stream/parser/spec.js b/src/core/json/stream/parser/spec.ts similarity index 95% rename from src/core/json/stream/parser/spec.js rename to src/core/json/stream/parser/spec.ts index d25c0652f..098eccd78 100644 --- a/src/core/json/stream/parser/spec.js +++ b/src/core/json/stream/parser/spec.ts @@ -8,14 +8,14 @@ * https://github.com/V4Fire/Core/blob/master/LICENSE */ -import Parser from 'core/json/stream/parser'; +import Parser, { Token } from 'core/json/stream/parser'; describe('core/json/stream/parser', () => { describe('parsing of primitive values', () => { it('integer numbers', async () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('100500')) { tokens.push(token); @@ -36,7 +36,7 @@ describe('core/json/stream/parser', () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('-12')) { tokens.push(token); @@ -56,7 +56,7 @@ describe('core/json/stream/parser', () => { it('numbers with a floating points', async () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('12.3')) { tokens.push(token); @@ -75,7 +75,7 @@ describe('core/json/stream/parser', () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('-12.300')) { tokens.push(token); @@ -99,7 +99,7 @@ describe('core/json/stream/parser', () => { it('numbers in an exponential form', async () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('12e10')) { tokens.push(token); @@ -119,7 +119,7 @@ describe('core/json/stream/parser', () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('-1E2')) { tokens.push(token); @@ -138,7 +138,7 @@ describe('core/json/stream/parser', () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('-1.4e2')) { tokens.push(token); @@ -159,7 +159,7 @@ describe('core/json/stream/parser', () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('4.4e-2')) { tokens.push(token); @@ -180,7 +180,7 @@ describe('core/json/stream/parser', () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('-4.4e-2')) { tokens.push(token); @@ -204,7 +204,7 @@ describe('core/json/stream/parser', () => { it('strings', async () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from('"foo bar"')) { tokens.push(token); @@ -226,7 +226,7 @@ describe('core/json/stream/parser', () => { { const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from(['"foo\t\tbar"'])) { tokens.push(token); @@ -292,7 +292,7 @@ describe('core/json/stream/parser', () => { }; const - tokens = []; + tokens: Token[] = []; for await (const token of Parser.from(createChunkIterator(input, 3))) { tokens.push(token); @@ -382,7 +382,7 @@ describe('core/json/stream/parser', () => { const iter = createChunkIterator(input, 10), - tokens = []; + tokens: Token[] = []; for (const chunk of iter) { for (const token of parser.processChunk(chunk)) { @@ -443,7 +443,7 @@ describe('core/json/stream/parser', () => { it('should throw an error if a JSON chunk is invalid', () => { const parser = new Parser(), - tokens = []; + tokens: Token[] = []; const input = '{"key1":1}garbage{"key3":2}', @@ -463,7 +463,7 @@ describe('core/json/stream/parser', () => { it("should throw an error if double quotes don't wrap a JSON object key", () => { const parser = new Parser(), - tokens = []; + tokens: Token[] = []; const input = '{key: 1}', @@ -483,7 +483,7 @@ describe('core/json/stream/parser', () => { it('should throw an error if single quotes wrap a JSON object key', () => { const parser = new Parser(), - tokens = []; + tokens: Token[] = []; const input = "{'key': 1}", @@ -501,9 +501,9 @@ describe('core/json/stream/parser', () => { }); }); -function createChunkIterator(input, step = 1) { +function createChunkIterator(input: Dictionary | string, step: number = 1) { const - data = typeof input === 'string' ? input : JSON.stringify(input); + data = Object.isString(input) ? input : JSON.stringify(input); let index = 0; diff --git a/src/core/json/stream/spec.js b/src/core/json/stream/spec.ts similarity index 93% rename from src/core/json/stream/spec.js rename to src/core/json/stream/spec.ts index faa3f12fc..41844c729 100644 --- a/src/core/json/stream/spec.js +++ b/src/core/json/stream/spec.ts @@ -9,12 +9,14 @@ import { intoIter } from 'core/iter'; import { sequence } from 'core/iter/combinators'; import { from, filter, pick, andPick, assemble, streamArray, streamObject } from 'core/json/stream'; +import type { Token } from 'core/json/stream/parser'; +import type { StreamedArray, StreamedObject } from 'core/json/stream/streamers'; describe('core/json/stream', () => { describe('`from`', () => { it('should parse sync JSON stream to tokens', async () => { const - tokens = []; + tokens: Token[] = []; for await (const token of from(['[1, {"a": 1}, true]'])) { tokens.push(token); @@ -43,7 +45,7 @@ describe('core/json/stream', () => { it('should parse async JSON stream to tokens', async () => { const - tokens = []; + tokens: Token[] = []; for await (const token of from(intoAsyncIter(['[1, {"a', '": 1},', 'true]']))) { tokens.push(token); @@ -74,7 +76,7 @@ describe('core/json/stream', () => { describe('filters', () => { it('should filter JSON tokens and preserves only that matched to a filter', async () => { const - tokens = []; + tokens: Token[] = []; for await (const token of filter(from(['{"a": 1, "b": 2, "data": [1, 2, 3]}']), /data/)) { tokens.push(token); @@ -106,7 +108,7 @@ describe('core/json/stream', () => { it('should pick tokens from a stream by the specified selector', async () => { const - tokens = []; + tokens: Token[] = []; for await (const token of pick(from('{"a": 1, "b": 2, "data": [1, 2, 3]}'), /data/)) { tokens.push(token); @@ -147,7 +149,7 @@ describe('core/json/stream', () => { ); const - res = []; + res: any[] = []; for await (const val of seq) { res.push(val); @@ -183,7 +185,7 @@ describe('core/json/stream', () => { describe('streamers', () => { it('should stream array elements from JSON tokens', async () => { const - elements = []; + elements: StreamedArray[] = []; for await (const el of streamArray(from('[{"a": 1}, true, 0.1e12]'))) { elements.push(el); @@ -198,7 +200,7 @@ describe('core/json/stream', () => { it('should stream object elements from JSON tokens', async () => { const - elements = []; + elements: StreamedObject[] = []; for await (const el of streamObject(from('{"a": 1, "b": [1, 2], "c": true, "d": {"a": 1}'))) { elements.push(el); @@ -214,7 +216,7 @@ describe('core/json/stream', () => { }); }); -async function* intoAsyncIter(source) { +async function* intoAsyncIter(source: Iterable) { for (const val of source) { await new Promise((resolve) => setTimeout(resolve, 10)); yield val; diff --git a/src/core/json/stream/streamers/spec.js b/src/core/json/stream/streamers/spec.ts similarity index 100% rename from src/core/json/stream/streamers/spec.js rename to src/core/json/stream/streamers/spec.ts diff --git a/src/core/kv-storage/interface.ts b/src/core/kv-storage/interface.ts index ca07b3e62..0e88548eb 100644 --- a/src/core/kv-storage/interface.ts +++ b/src/core/kv-storage/interface.ts @@ -110,7 +110,7 @@ export interface StorageEngine { exists?(key: unknown): unknown; includes?(key: unknown): unknown; has?(key: unknown): unknown; - keys?(): Iterable; + keys?(): Promise>; clear?(): unknown; clearAll?(): unknown; truncate?(): unknown; diff --git a/src/core/lazy/spec.js b/src/core/lazy/spec.ts similarity index 75% rename from src/core/lazy/spec.js rename to src/core/lazy/spec.ts index e225653ca..abfe69148 100644 --- a/src/core/lazy/spec.js +++ b/src/core/lazy/spec.ts @@ -11,12 +11,12 @@ import makeLazy from 'core/lazy'; describe('core/lazy', () => { it('should create a structure based on the passed function', () => { const - scan = []; + scan: string[] = []; - function createObj(a) { + function createObj(a: number) { return { a, - bla(...args) { + bla(...args: string[]) { scan.push(...args); } }; @@ -40,18 +40,21 @@ describe('core/lazy', () => { it('should create a structure based on the passed class', () => { const - scan = []; + scan: string[] = []; class User { - constructor(name, age) { - this.name = name; - this.age = age; + name: string; + age: number; - this.config = { + config: {attr?: string; errorHandler(): void} = { errorHandler() { - scan.push('errorHandler'); - } - }; + scan.push('errorHandler'); + } + }; + + constructor(name: string, age: number) { + this.name = name; + this.age = age; } sayName() { @@ -83,18 +86,21 @@ describe('core/lazy', () => { it('creating two instances of the one lazy structure based on a class', () => { const - scan = []; + scan: string[] = []; class User { - constructor(name, age) { + name: string; + age: number; + + config: Dictionary = { + errorHandler() { + scan.push('errorHandler'); + } + }; + + constructor(name: string, age: number) { this.name = name; this.age = age; - - this.config = { - errorHandler() { - scan.push('errorHandler'); - } - }; } sayName() { @@ -132,7 +138,12 @@ describe('core/lazy', () => { cache = {}; class RenderEngine { - component(name, opts) { + config: {attr: Dictionary | string; errorHandler(): void} = { + attr: {}, + errorHandler: Function + }; + + component(name: string, opts?: Dictionary) { if (opts == null) { return cache[name]; } @@ -154,30 +165,30 @@ describe('core/lazy', () => { { get: { - 'config.attrs'(contexts) { - return contexts.at(-1).config.attrs; + 'config.attrs'(contexts: RenderEngine[]) { + return contexts.at(-1)?.config.attr; } }, set: { - 'config.attrs'(contexts, value) { + 'config.attrs'(contexts: RenderEngine[], value: unknown) { contexts.forEach((ctx) => { - ctx.config.attrs = value; + ctx.config.attr = value; }); } }, call: { - component(contexts, ...args) { + component(contexts: RenderEngine[], ...args: unknown[]) { if (args.length > 1) { contexts.forEach((ctx) => { - ctx.component(...args); + ctx.component(args[0], args[1]); }); return true; } - return contexts.at(-1).component(...args); + return contexts.at(-1)?.component(args[0]); } } } diff --git a/src/core/linked-list/spec.js b/src/core/linked-list/spec.ts similarity index 100% rename from src/core/linked-list/spec.js rename to src/core/linked-list/spec.ts diff --git a/src/core/log/middlewares/errors-deduplicator/spec.js b/src/core/log/middlewares/errors-deduplicator/spec.ts similarity index 88% rename from src/core/log/middlewares/errors-deduplicator/spec.js rename to src/core/log/middlewares/errors-deduplicator/spec.ts index db7c79e4a..908216b60 100644 --- a/src/core/log/middlewares/errors-deduplicator/spec.js +++ b/src/core/log/middlewares/errors-deduplicator/spec.ts @@ -6,7 +6,7 @@ * https://github.com/V4Fire/Core/blob/master/LICENSE */ -import middlewareFactory from 'core/log/middlewares'; +import middlewareFactory, { LogEvent } from 'core/log/middlewares'; import { ErrorsDeduplicatorMiddleware } from 'core/log/middlewares/errors-deduplicator'; let middleware; @@ -80,32 +80,24 @@ describe('middlewares/errors-deduplicator', () => { expect(secondNextCallbackSpy).toHaveBeenCalledTimes(1); }); - function createLogEvent(error, context = 'test') { - const logEvent = { + function createLogEvent(error?: Error, context: string = 'test'): LogEvent { + return { context, - level: error ? 'error' : 'info', - additionals: {} + details: {}, + level: error != null ? 'error' : 'info', + additionals: {}, + error }; - - if (error) { - logEvent.error = error; - } - - return logEvent; } - function copyLogEvent(srcLogEvent) { - const copy = { + function copyLogEvent(srcLogEvent: LogEvent): LogEvent { + return { context: srcLogEvent.context, + details: srcLogEvent.details, level: srcLogEvent.level, - additionals: srcLogEvent.additionals + additionals: srcLogEvent.additionals, + error: srcLogEvent.error }; - - if (srcLogEvent.error) { - copy.error = srcLogEvent.error; - } - - return copy; } }); diff --git a/src/core/log/middlewares/extractor/spec.js b/src/core/log/middlewares/extractor/spec.ts similarity index 86% rename from src/core/log/middlewares/extractor/spec.js rename to src/core/log/middlewares/extractor/spec.ts index b502a9e3a..6d420adaf 100644 --- a/src/core/log/middlewares/extractor/spec.js +++ b/src/core/log/middlewares/extractor/spec.ts @@ -7,7 +7,16 @@ */ import { ExtractorMiddleware } from 'core/log/middlewares/extractor'; -import { TestDetailedError, TestBaseError, TestDetailedBaseError, TestExtractor } from 'core/log/middlewares/extractor/testing'; +import { + + TestBaseError, + TestDetailedBaseError, + TestDetailedError, + TestExtractor + +} from 'core/log/middlewares/extractor/testing'; + +import type { LogEvent } from 'core/log/middlewares'; let middleware; @@ -151,31 +160,23 @@ describe('middlewares/extractor', () => { }); }); - function createLogEvent(error) { - const logEvent = { - context: 'test', - level: error ? 'error' : 'info', - additionals: {} + function createLogEvent(error?: Error, context: string = 'test'): LogEvent { + return { + context, + details: {}, + level: error != null ? 'error' : 'info', + additionals: {}, + error }; - - if (error) { - logEvent.error = error; - } - - return logEvent; } - function copyLogEvent(srcLogEvent, additionals) { - const copy = { + function copyLogEvent(srcLogEvent: LogEvent, additionals?: Dictionary): LogEvent { + return { context: srcLogEvent.context, + details: srcLogEvent.details, level: srcLogEvent.level, - additionals: additionals ?? srcLogEvent.additionals + additionals: additionals ?? srcLogEvent.additionals, + error: srcLogEvent.error }; - - if (srcLogEvent.error) { - copy.error = srcLogEvent.error; - } - - return copy; } }); diff --git a/src/core/log/middlewares/extractor/testing.ts b/src/core/log/middlewares/extractor/testing.ts index a05d96ab3..26903f452 100644 --- a/src/core/log/middlewares/extractor/testing.ts +++ b/src/core/log/middlewares/extractor/testing.ts @@ -22,7 +22,7 @@ export class TestBaseError extends BaseError {} export class TestDetailedBaseError extends BaseError { readonly reason: unknown; - constructor(message: string, reason: unknown, cause: Error) { + constructor(message: string, reason: unknown, cause?: Error) { super(message, cause); this.reason = reason; } diff --git a/src/core/mime-type/spec.js b/src/core/mime-type/spec.ts similarity index 100% rename from src/core/mime-type/spec.js rename to src/core/mime-type/spec.ts diff --git a/src/core/net/spec.js b/src/core/net/spec.ts similarity index 100% rename from src/core/net/spec.js rename to src/core/net/spec.ts diff --git a/src/core/object/proxy-clone/spec.js b/src/core/object/proxy-clone/spec.ts similarity index 76% rename from src/core/object/proxy-clone/spec.js rename to src/core/object/proxy-clone/spec.ts index 696e2c3b9..1dca9ba9e 100644 --- a/src/core/object/proxy-clone/spec.js +++ b/src/core/object/proxy-clone/spec.ts @@ -10,7 +10,7 @@ import proxyClone from 'core/object/proxy-clone'; describe('core/object/proxy-clone', () => { it('cloning an object', () => { - const original = { + const original: {user: {name?: string; age: number; skills: string[]}} = { user: { name: 'Bob', age: 56, @@ -39,7 +39,7 @@ describe('core/object/proxy-clone', () => { }); it('getting `Object.keys` from the clone object', () => { - const original = { + const original: Dictionary> = { a: 1, b: [1, 2, 3] }; @@ -52,8 +52,8 @@ describe('core/object/proxy-clone', () => { expect(Object.keys(clone)).toEqual(['b', 'c']); - clone.b.push(4); - expect(Object.keys(clone.b)).toEqual(['0', '1', '2', '3']); + (clone.b).push(4); + expect(Object.keys(Object.cast(clone.b))).toEqual(['0', '1', '2', '3']); }); it('cloning an object with accessors', () => { @@ -69,7 +69,7 @@ describe('core/object/proxy-clone', () => { return this._age; }, - set age(value) { + set age(value: number) { this._age = value * 2; } } @@ -78,6 +78,8 @@ describe('core/object/proxy-clone', () => { const clone = proxyClone(original); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore expect(() => clone.user.name = 'Jack') .toThrowError("'set' on proxy: trap returned falsish for property 'name'"); @@ -86,6 +88,8 @@ describe('core/object/proxy-clone', () => { expect(clone.user.age).toBe(10); expect(original.user.age).toBe(56); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore delete clone.user.name; expect(clone.user.name).toBe(undefined); @@ -95,7 +99,7 @@ describe('core/object/proxy-clone', () => { }); it('cloning an object with descriptors', () => { - const original = { + const original: {user: {age?: number; name: string; newAge?: number}; bla?: number} = { user: { name: 'Bob' } @@ -175,7 +179,7 @@ describe('core/object/proxy-clone', () => { }); it('cloning an array', () => { - const original = [ + const original: Array<{name: string; age: number; skills?: string[]}> = [ { name: 'Bob', age: 56, @@ -187,7 +191,7 @@ describe('core/object/proxy-clone', () => { clone = proxyClone(original); clone[0].name = 'Jack'; - clone[0].skills.push('boxing'); + clone[0].skills?.push('boxing'); clone.push({ name: 'Sam', @@ -238,15 +242,15 @@ describe('core/object/proxy-clone', () => { const clone = proxyClone(original); - clone.get('user').name = 'Jack'; - clone.get('user').skills.add('boxing'); + clone.get('user')!.name = 'Jack'; + clone.get('user')?.skills.add('boxing'); - expect(clone.get('user').name).toBe('Jack'); - expect(original.get('user').name).toBe('Bob'); + expect(clone.get('user')?.name).toBe('Jack'); + expect(original.get('user')?.name).toBe('Bob'); - expect(clone.get('user').skills).toBeInstanceOf(Set); - expect([...clone.get('user').skills]).toEqual(['singing', 'dancing', 'programming', 'boxing']); - expect([...original.get('user').skills]).toEqual(['singing', 'dancing', 'programming']); + expect(clone.get('user')?.skills).toBeInstanceOf(Set); + expect([...clone.get('user')!.skills]).toEqual(['singing', 'dancing', 'programming', 'boxing']); + expect([...original.get('user')!.skills]).toEqual(['singing', 'dancing', 'programming']); }); it('cloning an object with WeakMap/WeakSet properties', () => { @@ -272,15 +276,15 @@ describe('core/object/proxy-clone', () => { const clone = proxyClone(original); - clone.get(user).name = 'Jack'; - clone.get(user).skills.add(boxing); + clone.get(user)!.name = 'Jack'; + clone.get(user)?.skills.add(boxing); - expect(clone.get(user).name).toBe('Jack'); - expect(original.get(user).name).toBe('Bob'); + expect(clone.get(user)?.name).toBe('Jack'); + expect(original.get(user)?.name).toBe('Bob'); - expect(clone.get(user).skills).toBeInstanceOf(WeakSet); - expect(clone.get(user).skills.has(boxing)).toBe(true); - expect(original.get(user).skills.has(boxing)).toBe(false); + expect(clone.get(user)?.skills).toBeInstanceOf(WeakSet); + expect(clone.get(user)?.skills.has(boxing)).toBe(true); + expect(original.get(user)?.skills.has(boxing)).toBe(false); }); it('cloning an iterable object', () => { @@ -300,30 +304,30 @@ describe('core/object/proxy-clone', () => { const clone = proxyClone(original); - for (const el of clone.get('user').skills) { + for (const el of clone.get('user')!.skills) { el.type = [...el.type].reverse().join(''); } - expect([...clone.get('user').skills]).toEqual([ + expect([...clone.get('user')!.skills]).toEqual([ {type: 'gnignis'}, {type: 'gnicnad'} ]); - expect([...original.get('user').skills]).toEqual([ + expect([...original.get('user')!.skills]).toEqual([ {type: 'singing'}, {type: 'dancing'} ]); - for (const el of clone.get('user').skillsSet) { + for (const el of clone.get('user')!.skillsSet) { el.type = [...el.type].reverse().join(''); } - expect([...clone.get('user').skillsSet]).toEqual([ + expect([...clone.get('user')!.skillsSet]).toEqual([ {type: 'gnignis'}, {type: 'gnicnad'} ]); - expect([...original.get('user').skillsSet]).toEqual([ + expect([...original.get('user')!.skillsSet]).toEqual([ {type: 'singing'}, {type: 'dancing'} ]); diff --git a/src/core/object/proxy-readonly/spec.js b/src/core/object/proxy-readonly/spec.ts similarity index 76% rename from src/core/object/proxy-readonly/spec.js rename to src/core/object/proxy-readonly/spec.ts index 7a4efd28a..1ad6b72f3 100644 --- a/src/core/object/proxy-readonly/spec.js +++ b/src/core/object/proxy-readonly/spec.ts @@ -10,7 +10,15 @@ import proxyReadonly from 'core/object/proxy-readonly'; describe('core/object/proxy-readonly', () => { it('readonly object', () => { - const original = { + interface User { + user: { + name?: string; + age: number; + skills: string[]; + }; + } + + const original: User = { user: { name: 'Bob', age: 56, @@ -61,17 +69,17 @@ describe('core/object/proxy-readonly', () => { const readonly = proxyReadonly(original); - expect(() => readonly.get('user').name = 'Jack') + expect(() => readonly.get('user')!.name = 'Jack') .toThrowError("'set' on proxy: trap returned falsish for property 'name'"); - readonly.get('user').skills.add('boxing'); + readonly.get('user')?.skills.add('boxing'); - expect(readonly.get('user').name).toBe('Bob'); - expect(original.get('user').name).toBe('Bob'); + expect(readonly.get('user')?.name).toBe('Bob'); + expect(original.get('user')?.name).toBe('Bob'); - expect(readonly.get('user').skills).toBeInstanceOf(Set); - expect([...readonly.get('user').skills]).toEqual(['singing', 'dancing', 'programming']); - expect([...original.get('user').skills]).toEqual(['singing', 'dancing', 'programming']); + expect(readonly.get('user')?.skills).toBeInstanceOf(Set); + expect([...readonly.get('user')!.skills]).toEqual(['singing', 'dancing', 'programming']); + expect([...original.get('user')!.skills]).toEqual(['singing', 'dancing', 'programming']); }); it('readonly object with WeakMap/WeakSet properties', () => { @@ -97,17 +105,17 @@ describe('core/object/proxy-readonly', () => { const readonly = proxyReadonly(original); - expect(() => readonly.get(user).name = 'Jack') + expect(() => readonly.get(user)!.name = 'Jack') .toThrowError("'set' on proxy: trap returned falsish for property 'name'"); - readonly.get(user).skills.add(boxing); + readonly.get(user)?.skills.add(boxing); - expect(readonly.get(user).name).toBe('Bob'); - expect(original.get(user).name).toBe('Bob'); + expect(readonly.get(user)?.name).toBe('Bob'); + expect(original.get(user)?.name).toBe('Bob'); - expect(readonly.get(user).skills).toBeInstanceOf(WeakSet); - expect(readonly.get(user).skills.has(boxing)).toBe(false); - expect(original.get(user).skills.has(boxing)).toBe(false); + expect(readonly.get(user)?.skills).toBeInstanceOf(WeakSet); + expect(readonly.get(user)?.skills.has(boxing)).toBe(false); + expect(original.get(user)?.skills.has(boxing)).toBe(false); }); it('readonly iterable object', () => { @@ -127,32 +135,32 @@ describe('core/object/proxy-readonly', () => { const readonly = proxyReadonly(original); - for (const el of readonly.get('user').skills) { + for (const el of readonly.get('user')!.skills) { expect(() => el.type = [...el.type].reverse().join('')) .toThrowError("'set' on proxy: trap returned falsish for property 'type'"); } - expect([...readonly.get('user').skills]).toEqual([ + expect([...readonly.get('user')!.skills]).toEqual([ {type: 'singing'}, {type: 'dancing'} ]); - expect([...original.get('user').skills]).toEqual([ + expect([...original.get('user')!.skills]).toEqual([ {type: 'singing'}, {type: 'dancing'} ]); - for (const el of readonly.get('user').skillsSet) { + for (const el of readonly.get('user')!.skillsSet) { expect(() => el.type = [...el.type].reverse().join('')) .toThrowError("'set' on proxy: trap returned falsish for property 'type'"); } - expect([...readonly.get('user').skillsSet]).toEqual([ + expect([...readonly.get('user')!.skillsSet]).toEqual([ {type: 'singing'}, {type: 'dancing'} ]); - expect([...original.get('user').skillsSet]).toEqual([ + expect([...original.get('user')!.skillsSet]).toEqual([ {type: 'singing'}, {type: 'dancing'} ]); diff --git a/src/core/object/select/spec.js b/src/core/object/select/spec.ts similarity index 98% rename from src/core/object/select/spec.js rename to src/core/object/select/spec.ts index 7fbf4d6ec..bcd93c9f9 100644 --- a/src/core/object/select/spec.js +++ b/src/core/object/select/spec.ts @@ -182,7 +182,7 @@ describe('core/object/select', () => { }); it('`where` as an array', () => { - const obj = new Map([ + const obj = new Map([ [1, {foo: 1, bla: 2}], [{}, {baz: 3}] ]); diff --git a/src/core/object/watch/index.ts b/src/core/object/watch/index.ts index f73b501b7..c1f709ca3 100644 --- a/src/core/object/watch/index.ts +++ b/src/core/object/watch/index.ts @@ -98,6 +98,36 @@ function watch( handler?: MultipleWatchHandler ): Watcher; +/** + * Watches for changes of the specified object + * + * @param obj + * @param path - path to a property to watch + * @param opts - additional options + * @param [handler] - callback that is invoked on every mutation hook + */ +function watch( + obj: T, + path: WatchPath, + opts: WatchOptions & ({immediate: true}), + handler?: WatchHandler +): Watcher; + +/** + * Watches for changes of the specified object + * + * @param obj + * @param path - path to a property to watch + * @param opts - additional options + * @param [handler] - callback that is invoked on every mutation hook + */ +function watch( + obj: T, + path: WatchPath, + opts: WatchOptions & ({collapse: false; immediate: true}), + handler?: WatchHandler +): Watcher; + /** * Watches for changes of the specified object * diff --git a/src/core/perf/config/index.ts b/src/core/perf/config/index.ts index 654523623..e0f40185c 100644 --- a/src/core/perf/config/index.ts +++ b/src/core/perf/config/index.ts @@ -75,11 +75,15 @@ export function mergeConfigs(baseConfig: PerfConfig, ...configs: Array): RegExp[] | boolean { +function createFilters(filters: CanUndef): RegExp[] | boolean { if (filters == null || Object.isBoolean(filters)) { return filters ?? true; } + if (Object.isString(filters)) { + return [new RegExp(filters)]; + } + if (Object.isArray(filters)) { return filters.map((filter) => new RegExp(filter)); } diff --git a/src/core/perf/config/interface.ts b/src/core/perf/config/interface.ts index b38f627bf..349880cf9 100644 --- a/src/core/perf/config/interface.ts +++ b/src/core/perf/config/interface.ts @@ -38,7 +38,7 @@ export interface PerfTimerConfig { * Settings to filter perf events by groups */ export type PerfGroupFilters = { - [K in PerfGroup]?: PerfIncludeFilter | string[] | boolean; + [K in PerfGroup]?: PerfIncludeFilter | string[] | string | boolean; }; /** diff --git a/src/core/perf/config/spec.js b/src/core/perf/config/spec.ts similarity index 100% rename from src/core/perf/config/spec.js rename to src/core/perf/config/spec.ts diff --git a/src/core/perf/timer/engines/spec.js b/src/core/perf/timer/engines/spec.ts similarity index 100% rename from src/core/perf/timer/engines/spec.js rename to src/core/perf/timer/engines/spec.ts diff --git a/src/core/perf/timer/impl/spec.js b/src/core/perf/timer/impl/spec.ts similarity index 98% rename from src/core/perf/timer/impl/spec.js rename to src/core/perf/timer/impl/spec.ts index 2f8cdb99f..d88de5667 100644 --- a/src/core/perf/timer/impl/spec.js +++ b/src/core/perf/timer/impl/spec.ts @@ -71,7 +71,7 @@ describe('core/perf/timer/impl', () => { it('throws an exception if metrics name is not defined', () => { const runner = new PerfTimersRunner(testEngine); const timer = runner.createTimer('manual'); - expect(() => timer.start(undefined)).toThrowError('The metrics name should be defined'); + expect(() => timer.start(Object.cast(undefined))).toThrowError('The metrics name should be defined'); }); it('throws an exception if metrics name is empty', () => { @@ -189,7 +189,7 @@ describe('core/perf/timer/impl', () => { it('throws an exception if metrics name is not defined', () => { const runner = new PerfTimersRunner(testEngine); const timer = runner.createTimer('manual'); - expect(() => timer.markTimestamp(undefined)).toThrowError(); + expect(() => timer.markTimestamp(Object.cast(undefined))).toThrowError(); }); it('throws an exception if metrics name is empty', () => { @@ -330,7 +330,7 @@ describe('core/perf/timer/impl', () => { it('throws an exception if passed namespace is undefined', () => { const runner = new PerfTimersRunner(testEngine); const timer = runner.createTimer('network'); - expect(() => timer.namespace(undefined)).toThrowError(); + expect(() => timer.namespace(Object.cast(undefined))).toThrowError(); }); it('throws an exception if passed namespace is empty', () => { diff --git a/src/core/perf/timer/spec.js b/src/core/perf/timer/spec.ts similarity index 97% rename from src/core/perf/timer/spec.js rename to src/core/perf/timer/spec.ts index 3b1cf9731..1cc25a096 100644 --- a/src/core/perf/timer/spec.js +++ b/src/core/perf/timer/spec.ts @@ -63,6 +63,9 @@ describe('core/perf/timer', () => { const timer = factory.getTimer('components'); const timerId = timer.start('button'); expect(timerId).toBeTruthy(); + + const timerId2 = timer.start('auth'); + expect(timerId2).toBeFalsy(); }); }); @@ -130,8 +133,11 @@ describe('core/perf/timer', () => { it('returns timers that work only if they match to the passed filters settings', () => { const factory = getTimerFactory({engine: 'console', filters: {components: 'button$'}}); const timer = factory.getScopedTimer('components', 'main-page'); - const timerId = timer.start('auth'); + const timerId = timer.start('button'); expect(timerId).toBeTruthy(); + + const timerId2 = timer.start('auth'); + expect(timerId2).toBeFalsy(); }); }); }); @@ -186,7 +192,7 @@ describe('core/perf/timer', () => { const firstTimerId = firstTimer.start('parsing'); expect(firstTimerId).toBeTruthy(); - const secondTimer = secondFactory.getTimer('manual', 'helpers'); + const secondTimer = secondFactory.getTimer('manual'); const secondTimerId = secondTimer.start('parsing'); expect(secondTimerId).toBeTruthy(); diff --git a/src/core/pool/spec.js b/src/core/pool/spec.ts similarity index 94% rename from src/core/pool/spec.js rename to src/core/pool/spec.ts index 9857b9d98..0a151e3bf 100644 --- a/src/core/pool/spec.js +++ b/src/core/pool/spec.ts @@ -10,6 +10,8 @@ import Pool from 'core/pool'; +type PoolsHookArgs = [number[], Pool, ...unknown[]]; + describe('core/pool', () => { describe('constructor', () => { it('should create a pool with a zero size', () => { @@ -224,9 +226,9 @@ describe('core/pool', () => { }); it('attaching the `onTake` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { size: 1, onTake: (...args) => { scan.push(args); @@ -250,9 +252,9 @@ describe('core/pool', () => { }); it('attaching the `onFree` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { size: 1, onFree: (...args) => { scan.push(args); @@ -328,9 +330,9 @@ describe('core/pool', () => { }); it('attaching the `onTake` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool((...values) => [...values], { + const pool = new Pool((...values) => [...values], { onTake: (...args) => { scan.push(args); } @@ -361,9 +363,9 @@ describe('core/pool', () => { }); it('attaching the `onFree` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { onFree: (...args) => { scan.push(args); } @@ -424,9 +426,9 @@ describe('core/pool', () => { }); it('attaching the `onTake` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { size: 1, onTake: (...args) => { scan.push(args); @@ -629,9 +631,9 @@ describe('core/pool', () => { }); it('attaching the `onBorrow` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { size: 1, onBorrow: (...args) => { scan.push(args); @@ -661,9 +663,9 @@ describe('core/pool', () => { }); it('attaching the `onFree` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { size: 1, onFree: (...args) => { scan.push(args); @@ -745,9 +747,9 @@ describe('core/pool', () => { }); it('attaching the `onBorrow` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool((...values) => [...values], { + const pool = new Pool((...values) => [...values], { onBorrow: (...args) => { scan.push(args); } @@ -778,9 +780,9 @@ describe('core/pool', () => { }); it('attaching the `onFree` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { onFree: (...args) => { scan.push(args); } @@ -840,9 +842,9 @@ describe('core/pool', () => { }); it('attaching the `onBorrow` hook handler', () => { - const scan = []; + const scan: PoolsHookArgs[] = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { size: 1, onBorrow: (...args) => { scan.push(args); @@ -873,7 +875,7 @@ describe('core/pool', () => { describe('`clear`', () => { it('should clear all available and unavailable resources', async () => { const - scan = []; + scan: unknown[][] = []; const pool = new Pool((...values) => [...values], (i) => [i], { size: 3, @@ -898,7 +900,7 @@ describe('core/pool', () => { expect(pool.size).toBe(1); expect(pool.available).toBe(0); - expect(scan.sort(([a], [b]) => a - b)).toEqual([ + expect(scan.sort(([a], [b]) => a - b)).toEqual([ [0], [1], [2] @@ -906,9 +908,9 @@ describe('core/pool', () => { }); it('attaching the `onClear` hook handler', () => { - const scan = []; + const scan: Array<[Pool, ...unknown[]]> = []; - const pool = new Pool(() => [], { + const pool = new Pool(() => [], { size: 3, onClear: (...args) => { scan.push(args); diff --git a/src/core/prelude/date/create/spec.ts b/src/core/prelude/date/create/spec.ts index 4921938fa..8ebfcf1b8 100644 --- a/src/core/prelude/date/create/spec.ts +++ b/src/core/prelude/date/create/spec.ts @@ -49,12 +49,10 @@ describe('core/prelude/date/create', () => { it('new date based on templates: xxxx[.-/]xx[.-/]xx | xx[.-/]xx[.-/]xxxx', () => { const chunks = [ today.getFullYear(), - (today.getMonth() + 1).toString().padStart(2, 0), - today.getDate().toString().padStart(2, 0) + (today.getMonth() + 1).toString().padStart(2, '0'), + today.getDate().toString().padStart(2, '0') ]; - console.warn(chunks); - expect(Date.create(chunks.join('.'))).toEqual(today); expect(Date.create(chunks.slice().reverse().join('.'))).toEqual(today); diff --git a/src/core/prelude/function/monad/spec.ts b/src/core/prelude/function/monad/spec.ts index 7296306c5..95ed44e99 100644 --- a/src/core/prelude/function/monad/spec.ts +++ b/src/core/prelude/function/monad/spec.ts @@ -13,7 +13,7 @@ describe('core/prelude/function/monad', () => { expect(await square(2)).toBe(4); expect(await square(square(2))).toBe(16); - expect(await square(square.result()(2))).toBe(16); + expect(await square(await square.result()(2))).toBe(16); expect(await square(null).catch((e) => e)).toBe(null); expect(await square(undefined).catch((e) => e)).toBe(null); @@ -53,7 +53,7 @@ describe('core/prelude/function/monad', () => { it('`Object.Result`', async () => { const - square = (n) => n * n, + square = (n: number) => n * n, call = Object.Result((f, ...args) => f(...args)), read = Object.Result((v) => v); diff --git a/src/core/prelude/object/iterators/spec.ts b/src/core/prelude/object/iterators/spec.ts index 6193b7d3f..f56c4bf43 100644 --- a/src/core/prelude/object/iterators/spec.ts +++ b/src/core/prelude/object/iterators/spec.ts @@ -26,7 +26,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of a string', () => { const data = 'foo', - scan: Array<[string, null, Iterable]> = []; + scan: Array<[string, number, string]> = []; Object.forEach(data, (...args) => { scan.push(args); @@ -42,7 +42,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of a string with surrogate pairs', () => { const data = '😃😡', - scan = []; + scan: Array<[string, number, string]> = []; Object.forEach(data, (...args) => { scan.push(args); @@ -105,7 +105,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an object', () => { const data = {a: 1, b: 2, __proto__: {c: 3}}, - scan: Array<[number, string, Dictionary]> = []; + scan: Array<[any, string, Dictionary]> = []; Object.forEach(data, (...args) => { scan.push(args); @@ -120,10 +120,10 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an object with descriptors', () => { const data = {a: 1, b: 2, __proto__: {c: 3}}, - scan = []; + scan: Array<[Dictionary, string, typeof data]> = []; Object.forEach(data, {passDescriptor: true}, (...args) => { - scan.push(args); + scan.push(Object.cast(args)); }); expect(scan).toEqual([ @@ -138,7 +138,7 @@ describe('core/prelude/object/iterators/forEach', () => { scan = []; Object.forEach(data, {withDescriptor: true}, (...args) => { - scan.push(args); + scan.push(Object.cast(args)); }); expect(scan).toEqual([ @@ -150,10 +150,10 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an object with adding of inherited properties', () => { const data = {a: 1, b: 2, __proto__: {c: 3}}, - scan = []; + scan: Array<[number, string, typeof data]> = []; Object.forEach(data, {propsToIterate: 'all'}, (...args) => { - scan.push(args); + scan.push(Object.cast(args)); }); expect(scan).toEqual([ @@ -166,10 +166,10 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an object with adding of inherited properties (legacy)', () => { const data = {a: 1, b: 2, __proto__: {c: 3}}, - scan = []; + scan: Array<[number, string, typeof data]> = []; Object.forEach(data, {notOwn: true}, (...args) => { - scan.push(args); + scan.push(Object.cast(args)); }); expect(scan).toEqual([ @@ -182,10 +182,10 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an object with skipping of own properties', () => { const data = {a: 1, b: 2, __proto__: {c: 3}}, - scan = []; + scan: Array<[number, string, typeof data]> = []; Object.forEach(data, {propsToIterate: 'inherited'}, (...args) => { - scan.push(args); + scan.push(Object.cast(args)); }); expect(scan).toEqual([[3, 'c', data]]); @@ -194,10 +194,10 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an object with skipping of own properties (legacy)', () => { const data = {a: 1, b: 2, __proto__: {c: 3}}, - scan = []; + scan: Array<[number, string, typeof data]> = []; Object.forEach(data, {notOwn: -1}, (...args) => { - scan.push(args); + scan.push(Object.cast(args)); }); expect(scan).toEqual([[3, 'c', data]]); @@ -206,7 +206,7 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an object with non-enumerable properties', () => { const data = {a: 1}, - scan = []; + scan: Array<[number, string, Dictionary]> = []; Object.defineProperty(data, 'b', {value: 2}); @@ -224,10 +224,10 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an iterator with object flags', () => { const data = Object.assign([1, 2, 3].values(), {a: 1}), - scan = []; + scan: Array<[number, string, typeof data]> = []; Object.forEach(data, {propsToIterate: 'own'}, (...args) => { - scan.push(args); + scan.push(Object.cast(args)); }); expect(scan).toEqual([[1, 'a', expect.anything()]]); @@ -237,10 +237,10 @@ describe('core/prelude/object/iterators/forEach', () => { it('iteration of an iterator with object flags (legacy)', () => { const data = Object.assign([1, 2, 3].values(), {a: 1}), - scan = []; + scan: Array<[number, string, typeof data]> = []; Object.forEach(data, {notOwn: false}, (...args) => { - scan.push(args); + scan.push(Object.cast(args)); }); expect(scan).toEqual([[1, 'a', expect.anything()]]); From 6a580759ad410f17c03b4bbe801ed2e1fa78eb99 Mon Sep 17 00:00:00 2001 From: kz2d Date: Sun, 16 Oct 2022 18:12:45 +0300 Subject: [PATCH 16/20] boom: added two more modules --- .../helpers/add-emitter/interface.ts | 2 +- src/core/cache/decorators/persistent/index.ts | 8 +- src/core/cache/decorators/spec.ts | 2 +- src/core/json/spec.ts | 7 +- src/core/object/watch/index.ts | 17 +---- src/core/object/watch/{spec.js => spec.ts} | 73 ++++++++++--------- 6 files changed, 51 insertions(+), 58 deletions(-) rename src/core/object/watch/{spec.js => spec.ts} (94%) diff --git a/src/core/cache/decorators/helpers/add-emitter/interface.ts b/src/core/cache/decorators/helpers/add-emitter/interface.ts index 01f938e4e..fbb3bb61d 100644 --- a/src/core/cache/decorators/helpers/add-emitter/interface.ts +++ b/src/core/cache/decorators/helpers/add-emitter/interface.ts @@ -27,7 +27,7 @@ export interface MutationHandler { export interface CacheWithEmitter = Cache> extends Cache { /** @override */ - set(key: K, value: V, opts?: Parameters[2]): V; + set(key: K, value: V, opts?: Parameters[2] | {}): V; /** * Event emitter to produce mutation events diff --git a/src/core/cache/decorators/persistent/index.ts b/src/core/cache/decorators/persistent/index.ts index f9db60dd7..4e5909f3a 100644 --- a/src/core/cache/decorators/persistent/index.ts +++ b/src/core/cache/decorators/persistent/index.ts @@ -16,6 +16,7 @@ import type Cache from 'core/cache/interface'; import PersistentWrapper from 'core/cache/decorators/persistent/wrapper'; import type { PersistentCache, PersistentOptions } from 'core/cache/decorators/persistent/interface'; +import type { CacheWithEmitter } from 'core/cache/decorators/helpers/add-emitter'; export * from 'core/cache/decorators/persistent/interface'; @@ -49,10 +50,11 @@ export * from 'core/cache/decorators/persistent/interface'; * copyOfCache = await addPersistent(new SimpleCache(), asyncLocal, opts); * ``` */ -const addPersistent = ( - cache: Cache, +const addPersistent = = Cache>( + cache: T, storage: SyncStorageNamespace | AsyncStorageNamespace, opts?: PersistentOptions -): Promise> => new PersistentWrapper, V>(cache, storage, opts).getInstance(); +): Promise>> => + new PersistentWrapper(cache, storage, opts).getInstance(); export default addPersistent; diff --git a/src/core/cache/decorators/spec.ts b/src/core/cache/decorators/spec.ts index e13dba1ab..ca451da91 100644 --- a/src/core/cache/decorators/spec.ts +++ b/src/core/cache/decorators/spec.ts @@ -8,7 +8,7 @@ import { asyncLocal } from 'core/kv-storage'; -import addPersistent, {PersistentOptions} from 'core/cache/decorators/persistent'; +import addPersistent, { PersistentOptions } from 'core/cache/decorators/persistent'; import addTTL from 'core/cache/decorators/ttl'; import RestrictedCache from 'core/cache/restricted'; diff --git a/src/core/json/spec.ts b/src/core/json/spec.ts index 9d3b44a10..f1593a6c0 100644 --- a/src/core/json/spec.ts +++ b/src/core/json/spec.ts @@ -45,7 +45,12 @@ describe('core/json', () => { }); }); -function testConvertIfDateCasesByDateParts(templateParts, dateParts, delimiter, expectedDate) { +function testConvertIfDateCasesByDateParts( + templateParts: string[], + dateParts: Array, + delimiter: string, + expectedDate: Date | string +) { const dateTemplate = templateParts.join(delimiter), dateString = dateParts.join(delimiter); diff --git a/src/core/object/watch/index.ts b/src/core/object/watch/index.ts index c1f709ca3..243600331 100644 --- a/src/core/object/watch/index.ts +++ b/src/core/object/watch/index.ts @@ -113,21 +113,6 @@ function watch( handler?: WatchHandler ): Watcher; -/** - * Watches for changes of the specified object - * - * @param obj - * @param path - path to a property to watch - * @param opts - additional options - * @param [handler] - callback that is invoked on every mutation hook - */ -function watch( - obj: T, - path: WatchPath, - opts: WatchOptions & ({collapse: false; immediate: true}), - handler?: WatchHandler -): Watcher; - /** * Watches for changes of the specified object * @@ -140,7 +125,7 @@ function watch( obj: T, path: WatchPath, opts: WatchOptions, - handler?: MultipleWatchHandler + handler?: WatchHandler ): Watcher; // eslint-disable-next-line max-lines-per-function diff --git a/src/core/object/watch/spec.js b/src/core/object/watch/spec.ts similarity index 94% rename from src/core/object/watch/spec.js rename to src/core/object/watch/spec.ts index ab29774bd..0d7b2b31b 100644 --- a/src/core/object/watch/spec.js +++ b/src/core/object/watch/spec.ts @@ -7,7 +7,7 @@ * https://github.com/V4Fire/Core/blob/master/LICENSE */ -import watch, { mute, unmute, unwatchable, set, unset, isProxy } from 'core/object/watch'; +import watch, { mute, unmute, unwatchable, set, unset, isProxy, WatchOptions } from 'core/object/watch'; import * as proxyEngine from 'core/object/watch/engines/proxy'; import * as accEngine from 'core/object/watch/engines/accessors'; @@ -87,7 +87,7 @@ describe('core/object/watch', () => { it('deep watching for an object', () => { const - obj = {a: {b: [], c: {e: 1}}}, + obj = {a: {b: [], c: {e: 1}}}, spy = jest.fn(); const {proxy} = watch(obj, {immediate: true, deep: true, engine}, (value, oldValue) => { @@ -107,7 +107,7 @@ describe('core/object/watch', () => { it('deep watching for an object by a complex path', () => { const - obj = {a: {b: []}, c: {e: 1}}; + obj = {a: {b: []}, c: {e: 1}}; { const @@ -142,11 +142,12 @@ describe('core/object/watch', () => { it('deep watching for an object by a complex path with collapsing', async () => { const - obj = {a: {b: []}}; + obj = {a: {b: []}}; const spy = jest.fn(); + // WHAT A FUCK const {proxy} = watch(obj, 'a.b', {engine}, (value, oldValue, info) => { spy(value, oldValue, info.path, info.originalPath); }); @@ -160,7 +161,7 @@ describe('core/object/watch', () => { it('deep watching for an object by a complex path without collapsing', async () => { const - obj = {a: {b: []}}; + obj = {a: {b: []}}; const spy = jest.fn(); @@ -181,7 +182,7 @@ describe('core/object/watch', () => { it('deep watching for an array by a complex path without collapsing', async () => { const - obj = {a: {b: []}}; + obj = {a: {b: >>[]}}; const spy = jest.fn(); @@ -201,7 +202,7 @@ describe('core/object/watch', () => { expect(spy).toHaveBeenCalledWith({e: 2}, 1, ['a', 'b', '0'], ['a', 'b', 0]); if (engineName === 'proxy') { - proxy.a.b[0].e++; + proxy.a.b[0]['e']++; await new Promise((r) => setTimeout(r, 15)); expect(spy).toHaveBeenCalledWith(3, 2, ['a', 'b', '0'], ['a', 'b', 0, 'e']); @@ -210,7 +211,7 @@ describe('core/object/watch', () => { it('isolated watchers', () => { const - obj = {a: {b: [], c: {e: 1}}}, + obj = {a: {b: [], c: {e: 1}}}, spy1 = jest.fn().mockName('spy1'), spy2 = jest.fn().mockName('spy2'); @@ -233,7 +234,7 @@ describe('core/object/watch', () => { it('shared watchers', () => { const - obj = {a: {b: [], c: {e: 1}}}, + obj = {a: {b: [], c: {e: 1}}}, spy1 = jest.fn().mockName('spy1'), spy2 = jest.fn().mockName('spy2'); @@ -256,7 +257,7 @@ describe('core/object/watch', () => { it('deep watching for an object with prototypes', () => { const - obj = {a: {b: [], __proto__: {c: {e: 1}}}}, + obj: {a: {b: number[]; c?: {e: number}; __proto__: unknown}} = {a: {b: [], __proto__: {c: {e: 1}}}}, protoSpy = jest.fn().mockName('with the prototype'), nonProtoSpy = jest.fn().mockName('without the prototype'); @@ -272,14 +273,14 @@ describe('core/object/watch', () => { expect(protoSpy).toHaveBeenCalledWith([1, 2, 3], [], false); expect(nonProtoSpy).toHaveBeenCalledWith([1, 2, 3], [], false); - nonProtoProxy.a.c.e = 4; + nonProtoProxy.a.c!.e = 4; expect(protoSpy).toHaveBeenCalledWith(4, 1, true); expect(nonProtoSpy).toHaveBeenCalledTimes(1); }); it('deep watching with collapsing', (done) => { const - obj = {a: {b: [], c: {e: 1}}, c: []}, + obj = {a: {b: [], c: {e: 1}}, c: []}, spy = jest.fn(); const opts = { @@ -314,10 +315,10 @@ describe('core/object/watch', () => { it('deep watching with collapsing and the `immediate` option', () => { const - obj = {a: {b: [], c: {e: 1}}, c: []}, + obj = {a: {b: [], c: {e: 1}}, c: []}, spy = jest.fn(); - const opts = { + const opts: WatchOptions & ({immediate: true}) = { immediate: true, deep: true, collapse: true, @@ -367,7 +368,7 @@ describe('core/object/watch', () => { spy = jest.fn().mockName('global'), localSpy = jest.fn().mockName('local'); - const opts = { + const opts: WatchOptions & ({immediate: true}) = { immediate: true, deep: true, prefixes: ['_', '$'], @@ -433,7 +434,7 @@ describe('core/object/watch', () => { fooStore: ['b.$foo'] }, - new Map([ + new Map, CanArray>([ ['a', ['_a']], [['b', 'foo'], [['b', 'fooStore']]], ['fooStore', ['b.$foo']] @@ -446,7 +447,7 @@ describe('core/object/watch', () => { spy = jest.fn().mockName('global'), localSpy = jest.fn().mockName('local'); - const opts = { + const opts: WatchOptions & ({immediate: true}) = { immediate: true, deep: true, dependencies: deps[i], @@ -488,7 +489,7 @@ describe('core/object/watch', () => { const spy = jest.fn().mockName('global'); - const opts = { + const opts: WatchOptions & ({immediate: true}) = { immediate: true, dependencies: ['_a'], engine @@ -507,7 +508,7 @@ describe('core/object/watch', () => { it('watching for an array', () => { const - arr = [], + arr: number[] = [], spy = jest.fn(); const {proxy} = watch(arr, {immediate: true, engine}, (value, oldValue, info) => { @@ -564,8 +565,8 @@ describe('core/object/watch', () => { it('array concatenation with proxy', () => { const - arrOne = [1, 2, 3], - arrTwo = ['foo', 'bar']; + arrOne: Array = [1, 2, 3], + arrTwo: Array = ['foo', 'bar']; const {proxy: proxyOne} = watch(arrOne, {immediate: true, engine}), @@ -603,7 +604,7 @@ describe('core/object/watch', () => { it('watching for a set', () => { const - set = new Set([]), + set = new Set([]), spy = jest.fn(); const {proxy} = watch(set, {immediate: true, engine}, (value, oldValue, info) => { @@ -654,7 +655,7 @@ describe('core/object/watch', () => { it('watching for a weak set', () => { const - set = new WeakSet([]), + set = new WeakSet([]), spy = jest.fn(); const {proxy} = watch(set, {immediate: true, engine}, (value, oldValue, info) => { @@ -764,8 +765,8 @@ describe('core/object/watch', () => { it('tying a watcher to another object', () => { const - another = {}, obj = {a: 1, b: 2}, + another: Partial = {}, spy = jest.fn(); watch(obj, {immediate: true, tiedWith: another, engine}, (value, oldValue) => { @@ -839,7 +840,7 @@ describe('core/object/watch', () => { it('marking a part of the watched object as unwatchable', () => { const - obj = {a: 1, b: unwatchable({c: 2, d: {e: 3}}, engine)}, + obj = {a: 1, b: unwatchable({c: 2, d: {e: 3}})}, spy = jest.fn(); const {proxy, set} = watch(obj, {immediate: true, engine}, (value, oldValue, info) => { @@ -876,7 +877,7 @@ describe('core/object/watch', () => { it('setting of new properties', () => { { const - obj = {}, + obj: {a?: number} = {}, spy = jest.fn(); const {proxy, set} = watch(obj, {immediate: true, engine}, (value, oldValue, info) => { @@ -892,7 +893,7 @@ describe('core/object/watch', () => { { const - obj = {}, + obj: {a?: number} = {}, spy = jest.fn(); const {proxy} = watch(obj, {immediate: true, engine}, (value, oldValue, info) => { @@ -910,7 +911,7 @@ describe('core/object/watch', () => { it('deep setting of new properties', () => { { const - obj = {}, + obj: {a?: {b?: number}} = {}, spy = jest.fn(); const {proxy, set} = watch(obj, {immediate: true, engine, deep: true}, (value, oldValue, info) => { @@ -922,7 +923,7 @@ describe('core/object/watch', () => { expect(proxy.a?.b).toBe(1); expect(obj.a?.b).toBe(1); - proxy.a.b = 2; + proxy.a!.b = 2; expect(spy).toHaveBeenCalledWith(2, 1, ['a', 'b']); expect(proxy.a?.b).toBe(2); expect(obj.a?.b).toBe(2); @@ -930,7 +931,7 @@ describe('core/object/watch', () => { { const - obj = {}, + obj: {a?: {b?: number}} = {}, spy = jest.fn(); const {proxy} = watch(obj, {immediate: true, engine, deep: true}, (value, oldValue, info) => { @@ -942,7 +943,7 @@ describe('core/object/watch', () => { expect(proxy.a?.b).toBe(1); expect(obj.a?.b).toBe(1); - proxy.a.b = 2; + proxy.a!.b = 2; expect(spy).toHaveBeenCalledWith(2, 1, ['a', 'b']); expect(proxy.a?.b).toBe(2); expect(obj.a?.b).toBe(2); @@ -952,7 +953,7 @@ describe('core/object/watch', () => { it('deleting of properties', () => { { const - obj = {a: 1}, + obj: {a?: number} = {a: 1}, spy = jest.fn(); const {proxy} = watch(obj, {immediate: true, engine}, (value, oldValue, info) => { @@ -1013,20 +1014,20 @@ describe('core/object/watch', () => { it('modifying prototype values', () => { const - obj = {a: {a: 1}, __proto__: {b: {b: 1}}}, + obj: {a: {a: number}; b?: {b?: number}; __proto__: unknown} = {a: {a: 1}, __proto__: {b: {b: 1}}}, spy = jest.fn(); const {proxy} = watch(obj, {deep: true, immediate: true, withProto: true, engine}, (value, oldValue, info) => { spy(value, oldValue, info.path); }); - proxy.b.b++; + proxy.b!.b!++; expect(spy).toHaveBeenCalledWith(2, 1, ['b', 'b']); proxy.a.a++; expect(spy).toHaveBeenCalledWith(2, 1, ['a', 'a']); - expect(proxy.b.b).toBe(2); + expect(proxy.b?.b).toBe(2); expect(proxy.a.a).toBe(2); }); @@ -1039,7 +1040,7 @@ describe('core/object/watch', () => { if (engineName === 'proxy') { it("shouldn't wrap readonly non-configurable properties", () => { const - obj = {}, + obj: {foo?: Dictionary} = {}, nested = {a: 1}; Object.defineProperty(obj, 'foo', { From 6eadc9d82e6c70c196e8898b6540356775b0ed6c Mon Sep 17 00:00:00 2001 From: kz2d Date: Sun, 16 Oct 2022 19:12:15 +0300 Subject: [PATCH 17/20] Fix: types for add-emitter and json/stream/streans --- .../cache/decorators/helpers/add-emitter/spec.ts | 9 +++++---- src/core/json/stream/streamers/spec.ts | 14 +++++++------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/core/cache/decorators/helpers/add-emitter/spec.ts b/src/core/cache/decorators/helpers/add-emitter/spec.ts index 651b85019..b6df0263b 100644 --- a/src/core/cache/decorators/helpers/add-emitter/spec.ts +++ b/src/core/cache/decorators/helpers/add-emitter/spec.ts @@ -6,7 +6,7 @@ * https://github.com/V4Fire/Core/blob/master/LICENSE */ -import addEmitter, { eventEmitter } from 'core/cache/decorators/helpers/add-emitter'; +import addEmitter, { CacheWithEmitter, eventEmitter } from 'core/cache/decorators/helpers/add-emitter'; import SimpleCache from 'core/cache/simple'; import RestrictedCache from 'core/cache/restricted'; @@ -132,15 +132,16 @@ describe('core/cache/decorators/helpers/add-emitter', () => { it('sets a new value', () => { const cache = new SimpleCache(), - {set} = addEmitter(cache); + {set} = addEmitter(cache), + cacheEmitter = cache; const memory: any[] = []; - cache[eventEmitter].on('set', (...args) => { + cacheEmitter[eventEmitter].on('set', (...args) => { memory.push(args); }); - cache.set('foo', 1, {ttl: 100, cacheTTL: 200}); + cacheEmitter.set('foo', 1, {ttl: 100, cacheTTL: 200}); expect(memory[0]).toEqual([cache, {args: ['foo', 1, {ttl: 100, cacheTTL: 200}], result: 1}]); set('bar', 2); diff --git a/src/core/json/stream/streamers/spec.ts b/src/core/json/stream/streamers/spec.ts index 768263534..4d9b1d0af 100644 --- a/src/core/json/stream/streamers/spec.ts +++ b/src/core/json/stream/streamers/spec.ts @@ -9,7 +9,7 @@ import Parser from 'core/json/stream/parser'; import { Pick } from 'core/json/stream/filters'; -import { ArrayStreamer, ObjectStreamer } from 'core/json/stream/streamers'; +import { ArrayStreamer, ObjectStreamer, StreamedArray, StreamedObject } from 'core/json/stream/streamers'; describe('core/json/stream/streamers', () => { describe('`ArrayStreamer`', () => { @@ -23,7 +23,7 @@ describe('core/json/stream/streamers', () => { }`; const - tokens = []; + tokens: StreamedArray[] = []; for await (const token of Parser.from([data], new Pick('a.b'), new ArrayStreamer())) { tokens.push(token); @@ -39,7 +39,7 @@ describe('core/json/stream/streamers', () => { it('should stream nothing if the source array is empty', async () => { const - tokens = []; + tokens: StreamedArray[] = []; for await (const token of Parser.from(['[]'], new ArrayStreamer())) { tokens.push(token); @@ -53,7 +53,7 @@ describe('core/json/stream/streamers', () => { err; const - tokens = []; + tokens: StreamedArray[] = []; try { for await (const token of Parser.from(['{"a": 1}'], new ArrayStreamer())) { @@ -80,7 +80,7 @@ describe('core/json/stream/streamers', () => { }`; const - tokens = []; + tokens: StreamedObject[] = []; for await (const token of Parser.from([data], new ObjectStreamer())) { tokens.push(token); @@ -94,7 +94,7 @@ describe('core/json/stream/streamers', () => { it('should stream nothing if the source object is empty', async () => { const - tokens = []; + tokens: StreamedObject[] = []; for await (const token of Parser.from(['{}'], new ObjectStreamer())) { tokens.push(token); @@ -108,7 +108,7 @@ describe('core/json/stream/streamers', () => { err; const - tokens = []; + tokens: StreamedObject[] = []; try { for await (const token of Parser.from(['[1,2]'], new ObjectStreamer())) { From cd047dbaafddd8d3c440807d8ec8cb6bdb1b3934 Mon Sep 17 00:00:00 2001 From: kz2d Date: Sun, 16 Oct 2022 19:24:21 +0300 Subject: [PATCH 18/20] fix: merge request conflict --- src/core/prelude/date/format/spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/prelude/date/format/spec.ts b/src/core/prelude/date/format/spec.ts index a763bbf87..eef5feb4d 100644 --- a/src/core/prelude/date/format/spec.ts +++ b/src/core/prelude/date/format/spec.ts @@ -7,7 +7,8 @@ */ describe('core/prelude/date/format', () => { - const date = Date.create('18.10.1989 10:10:10'); + const date = + Date.create('18.10.1989 10:10:10'); it('`short`', () => { expect(date.short('en')).toBe('10/18/1989'); From 11608ee72075bd5b6b25e88df06c4139f64fb7ad Mon Sep 17 00:00:00 2001 From: kz2d Date: Sun, 16 Oct 2022 19:25:44 +0300 Subject: [PATCH 19/20] fix: merge request conflict --- src/core/prelude/date/format/spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/prelude/date/format/spec.ts b/src/core/prelude/date/format/spec.ts index eef5feb4d..9f324a888 100644 --- a/src/core/prelude/date/format/spec.ts +++ b/src/core/prelude/date/format/spec.ts @@ -7,8 +7,8 @@ */ describe('core/prelude/date/format', () => { - const date = - Date.create('18.10.1989 10:10:10'); + const + date = Date.create('18.10.1989 10:10:10'); it('`short`', () => { expect(date.short('en')).toBe('10/18/1989'); From 70205725e1262b585f088a0ece3b888bd9010645 Mon Sep 17 00:00:00 2001 From: kz2d Date: Sun, 16 Oct 2022 20:02:52 +0300 Subject: [PATCH 20/20] style: style fixes after self review --- index.d.ts | 2 +- src/core/object/watch/index.ts | 15 --------------- src/core/request/error/spec.ts | 9 ++------- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/index.d.ts b/index.d.ts index 43f70e8f2..47f9c8393 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2858,7 +2858,7 @@ interface RegExpConstructor { * @param rgxp * @param flags */ - addFlags(rgxp: RegExp, ...flags: [RegExpFlag, ...RegExpFlag[]]): RegExp; + addFlags(rgxp: RegExp, ...flags: [RegExpFlag, ...RegExpFlag[]]): RegExp; /** * Returns a curried version of `RegExp.addFlags` diff --git a/src/core/object/watch/index.ts b/src/core/object/watch/index.ts index 243600331..d0fea2070 100644 --- a/src/core/object/watch/index.ts +++ b/src/core/object/watch/index.ts @@ -98,21 +98,6 @@ function watch( handler?: MultipleWatchHandler ): Watcher; -/** - * Watches for changes of the specified object - * - * @param obj - * @param path - path to a property to watch - * @param opts - additional options - * @param [handler] - callback that is invoked on every mutation hook - */ -function watch( - obj: T, - path: WatchPath, - opts: WatchOptions & ({immediate: true}), - handler?: WatchHandler -): Watcher; - /** * Watches for changes of the specified object * diff --git a/src/core/request/error/spec.ts b/src/core/request/error/spec.ts index 3081ebb36..18f83c500 100644 --- a/src/core/request/error/spec.ts +++ b/src/core/request/error/spec.ts @@ -8,17 +8,14 @@ * https://github.com/V4Fire/Core/blob/master/LICENSE */ -import RequestError, { RequestErrorDetailsExtractor } from 'core/request/error'; +import RequestError, { Details, RequestErrorDetailsExtractor } from 'core/request/error'; import V4Headers from 'core/request/headers'; describe('core/request/error', () => { let err; beforeEach(() => { - // TODO - err = new RequestError(RequestError.Timeout, { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + err = new RequestError(RequestError.Timeout,
{ request: { url: 'url/url', @@ -35,8 +32,6 @@ describe('core/request/error', () => { foo: 'bla' }) }, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore response: { status: 404, body: 'not found',