chore(deps): upgrade all dependencies, toolchains and images (#2825)

This commit is contained in:
Hampus
2026-09-17 21:08:56 +02:00
committed by GitHub
parent 56e04e7b53
commit 3b552e00ef
510 changed files with 23614 additions and 37473 deletions
+2 -2
View File
@@ -9,12 +9,12 @@
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"@vitest/coverage-v8": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:",
"yaml": "catalog:"
}
+2 -2
View File
@@ -9,10 +9,10 @@
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@typescript/native-preview": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
+3 -1
View File
@@ -1,5 +1,7 @@
{
"extends": "../../tsconfigs/package.json",
"compilerOptions": {},
"compilerOptions": {
"types": []
},
"include": ["src/**/*"]
}
+2 -2
View File
@@ -7,7 +7,7 @@
"./*": "./*"
},
"scripts": {
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@fluxer/constants": "workspace:*",
@@ -15,6 +15,6 @@
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:"
"typescript": "catalog:ts7"
}
}
+1 -3
View File
@@ -1,7 +1,5 @@
{
"extends": "../../tsconfigs/package.json",
"compilerOptions": {
"types": ["node"]
},
"compilerOptions": {},
"include": ["src/**/*"]
}
+2 -2
View File
@@ -9,7 +9,7 @@
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@fluxer/config": "workspace:*",
@@ -23,7 +23,7 @@
"devDependencies": {
"@messageformat/parser": "catalog:",
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
@@ -51,26 +51,24 @@ describe('AppErrorHandler i18n fallbacks', () => {
requestId: undefined,
message: 'Internal server error.',
},
])('$name and logs unexpected errors with request metadata', async ({
acceptLanguage,
requestLocale,
requestId,
message,
}) => {
const errorLogger = vi.spyOn(Logger.prototype, 'error').mockImplementation(() => {});
const error = new Error('Private internal failure');
const headers = new Headers();
if (acceptLanguage !== undefined) {
headers.set('accept-language', acceptLanguage);
}
const response = await createApp(error, requestLocale, requestId).request('/test', {headers});
expect(response.status).toBe(500);
expect(await response.json()).toEqual({code: APIErrorCodes.INTERNAL_SERVER_ERROR, message});
expect(errorLogger).toHaveBeenCalledExactlyOnceWith(
{err: error, status: 500, method: 'GET', path: '/test', requestId},
'Unhandled error occurred',
);
});
])(
'$name and logs unexpected errors with request metadata',
async ({acceptLanguage, requestLocale, requestId, message}) => {
const errorLogger = vi.spyOn(Logger.prototype, 'error').mockImplementation(() => {});
const error = new Error('Private internal failure');
const headers = new Headers();
if (acceptLanguage !== undefined) {
headers.set('accept-language', acceptLanguage);
}
const response = await createApp(error, requestLocale, requestId).request('/test', {headers});
expect(response.status).toBe(500);
expect(await response.json()).toEqual({code: APIErrorCodes.INTERNAL_SERVER_ERROR, message});
expect(errorLogger).toHaveBeenCalledExactlyOnceWith(
{err: error, status: 500, method: 'GET', path: '/test', requestId},
'Unhandled error occurred',
);
},
);
it('localizes FluxerError responses without an i18n service and logs them as expected rejections', async () => {
const errorLogger = vi.spyOn(Logger.prototype, 'error').mockImplementation(() => {});
@@ -53,15 +53,14 @@ describe.each([
});
});
it.each([
BadRequestError,
ForbiddenError,
NotFoundError,
])('preserves custom messages for client errors', (ErrorClass) => {
const error = new ErrorClass({code: APIErrorCodes.INVALID_REQUEST, message: 'Custom error message'});
it.each([BadRequestError, ForbiddenError, NotFoundError])(
'preserves custom messages for client errors',
(ErrorClass) => {
const error = new ErrorClass({code: APIErrorCodes.INVALID_REQUEST, message: 'Custom error message'});
expect(error.toJSON()).toEqual({code: APIErrorCodes.INVALID_REQUEST, message: 'Custom error message'});
});
expect(error.toJSON()).toEqual({code: APIErrorCodes.INVALID_REQUEST, message: 'Custom error message'});
},
);
describe.each([
[APIErrorCodes.INVALID_PHONE_NUMBER, InvalidPhoneNumberError, BadRequestError, HttpStatus.BAD_REQUEST],
+2 -2
View File
@@ -7,13 +7,13 @@
"./*": "./*"
},
"scripts": {
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@fluxer/constants": "workspace:*"
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:"
"typescript": "catalog:ts7"
}
}
+2 -2
View File
@@ -8,7 +8,7 @@
},
"scripts": {
"test": "vitest run",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@fluxer/constants": "workspace:*",
@@ -19,7 +19,7 @@
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
+2 -2
View File
@@ -4,9 +4,9 @@
"private": true,
"type": "module",
"scripts": {
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@typescript/native-preview": "catalog:"
"typescript": "catalog:ts7"
}
}
+3 -1
View File
@@ -1,5 +1,7 @@
{
"extends": "../../tsconfigs/package.json",
"compilerOptions": {},
"compilerOptions": {
"types": []
},
"include": ["src/**/*"]
}
+2 -2
View File
@@ -15,7 +15,7 @@
"static:sync": "tsx scripts/SyncStaticI18nCatalogs.ts --extract --compile",
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@messageformat/core": "catalog:",
@@ -24,8 +24,8 @@
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"tsx": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
+1
View File
@@ -1,6 +1,7 @@
{
"extends": "../../tsconfigs/base.json",
"compilerOptions": {
"types": ["node"],
"outDir": "./dist",
"rootDir": "./src"
},
+2 -2
View File
@@ -8,7 +8,7 @@
"./*": "./*"
},
"scripts": {
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@fluxer/constants": "workspace:*",
@@ -17,6 +17,6 @@
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:"
"typescript": "catalog:ts7"
}
}
+2 -2
View File
@@ -9,12 +9,12 @@
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"@vitest/coverage-v8": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
+2 -2
View File
@@ -7,14 +7,14 @@
"./*": "./*"
},
"scripts": {
"typecheck": "tsgo --noEmit",
"typecheck": "tsc --noEmit",
"test": "vitest run"
},
"dependencies": {
"@fluxer/constants": "workspace:*"
},
"devDependencies": {
"@typescript/native-preview": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
+1 -2
View File
@@ -1,8 +1,7 @@
{
"extends": "../../tsconfigs/package.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
"types": []
},
"include": ["src/**/*"]
}
+2 -2
View File
@@ -6,7 +6,7 @@
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"dependencies": {
"pino": "catalog:",
@@ -14,7 +14,7 @@
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
+36 -52
View File
@@ -10,9 +10,9 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
[[package]]
name = "cc"
version = "1.2.63"
version = "1.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f"
checksum = "a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -22,15 +22,15 @@ dependencies = [
[[package]]
name = "cfg-if"
version = "1.0.4"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d"
[[package]]
name = "fluxer_markdown_parser"
@@ -51,14 +51,13 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.3.4"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasip2",
]
[[package]]
@@ -69,9 +68,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "jobserver"
version = "0.1.34"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3"
dependencies = [
"getrandom",
"libc",
@@ -79,15 +78,15 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.186"
version = "0.2.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
[[package]]
name = "libfuzzer-sys"
version = "0.4.12"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d"
checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2"
dependencies = [
"arbitrary",
"cc",
@@ -95,39 +94,39 @@ dependencies = [
[[package]]
name = "memchr"
version = "2.8.1"
version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
[[package]]
name = "proc-macro2"
version = "1.0.106"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "serde"
version = "1.0.228"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [
"serde_core",
"serde_derive",
@@ -135,18 +134,18 @@ dependencies = [
[[package]]
name = "serde_core"
version = "1.0.228"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [
"proc-macro2",
"quote",
@@ -155,9 +154,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.150"
version = "1.0.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
dependencies = [
"itoa",
"memchr",
@@ -174,9 +173,9 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "syn"
version = "2.0.117"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
dependencies = [
"proc-macro2",
"quote",
@@ -185,27 +184,12 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.24"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "wasip2"
version = "1.0.3+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wit-bindgen"
version = "0.57.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
[[package]]
name = "zmij"
version = "1.0.21"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
+2 -2
View File
@@ -9,7 +9,7 @@
"scripts": {
"generate": "tsx src/scripts/GenerateSpec.ts",
"test": "vitest run",
"typecheck": "tsgo --noEmit",
"typecheck": "tsc --noEmit",
"validate": "tsx src/scripts/GenerateSpec.ts --validate-only"
},
"dependencies": {
@@ -22,8 +22,8 @@
"devDependencies": {
"@biomejs/biome": "catalog:",
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"tsx": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
@@ -24,7 +24,7 @@ describe('native Zod conversion', () => {
expect(input.required).toEqual(['note']);
expect(output.required).toEqual(['name', 'note']);
expect(input.properties?.name).toMatchObject({type: 'string', default: 'guest'});
expect(input.properties?.note).toEqual({anyOf: [{type: 'string'}, {type: 'null'}]});
expect(input.properties?.note).toEqual({type: ['string', 'null']});
expect(input.additionalProperties).toBeUndefined();
expect(output.additionalProperties).toBe(false);
const document = documentFor(converter);
@@ -53,17 +53,17 @@ describe('discoverControllerFiles', () => {
const route = routes.find((route) => route.path === '/donations/manage');
expect(route?.explicitSecurity).toEqual([]);
});
it.each([
'download_latest_desktop_version_checksum',
'download_desktop_version_checksum',
])('preserves the plain-text checksum response for %s', (operationId) => {
const route = routes.find((route) => route.explicitOperationId === operationId);
expect(route).toMatchObject({
responseSchemaName: 'DownloadChecksumResponse',
responseContentType: 'text/plain',
explicitStatusCodes: [200],
});
});
it.each(['download_latest_desktop_version_checksum', 'download_desktop_version_checksum'])(
'preserves the plain-text checksum response for %s',
(operationId) => {
const route = routes.find((route) => route.explicitOperationId === operationId);
expect(route).toMatchObject({
responseSchemaName: 'DownloadChecksumResponse',
responseContentType: 'text/plain',
explicitStatusCodes: [200],
});
},
);
it('rejects a bodyless status that is absent from the route response statuses', () => {
const route = routes.find((route) => route.path === '/donations/manage');
assert(route);
@@ -19,19 +19,12 @@ describe('static route expressions', () => {
expect(resolveExpression(`paths[${JSON.stringify(index)}]`)).toBe(Number(index) === 0 ? '/first' : '/second');
});
it.each([
'1suffix',
'1.5',
'01',
'1e0',
' 1',
'',
'-0',
-1,
2,
])('does not coerce array property %j into a route index', (index) => {
expect(resolveExpression(`paths[${JSON.stringify(index)}]`)).toBe(UNRESOLVED);
});
it.each(['1suffix', '1.5', '01', '1e0', ' 1', '', '-0', -1, 2])(
'does not coerce array property %j into a route index',
(index) => {
expect(resolveExpression(`paths[${JSON.stringify(index)}]`)).toBe(UNRESOLVED);
},
);
});
describe('imported route constants', () => {
@@ -142,7 +142,7 @@ export class OpenAPIOperationBuilder {
const location = validator.target === 'param' ? 'path' : validator.target;
const schemaName = validator.schemaName;
const schema = this.schemaRegistry.get(schemaName);
if (!schema || schema.type !== 'object' || !schema.properties) {
if (schema?.type !== 'object' || !schema.properties) {
throw new Error(`Parameter schema must be an object: ${schemaName}`);
}
const required = new Set(schema.required ?? []);
+1
View File
@@ -2,6 +2,7 @@
"extends": "../../tsconfigs/base.json",
"compilerOptions": {
"lib": ["ESNext"],
"types": ["node"],
"paths": {
"@fluxer/*": ["./../../packages/*"]
}
+5 -5
View File
@@ -10,11 +10,11 @@
"test": "vitest run",
"test:coverage": "vitest run --coverage",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit",
"typecheck": "tsc --noEmit",
"generate": "cd proto && buf generate && ../../../tools/ci/run.sh clean-schema-generated-files --root ../src/gen && cd .. && pnpm exec biome check --write --unsafe --no-errors-on-unmatched src/gen"
},
"dependencies": {
"@bufbuild/protobuf": "^2.12.0",
"@bufbuild/protobuf": "^2.15.0",
"@fluxer/constants": "workspace:*",
"@simplewebauthn/server": "catalog:",
"emoji-regex": "catalog:",
@@ -23,11 +23,11 @@
"zod": "catalog:"
},
"devDependencies": {
"@bufbuild/buf": "^1.69.0",
"@bufbuild/protoc-gen-es": "^2.12.0",
"@bufbuild/buf": "^1.73.0",
"@bufbuild/protoc-gen-es": "^2.15.0",
"@types/node": "catalog:",
"@types/validator": "catalog:",
"@typescript/native-preview": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
@@ -31,14 +31,12 @@ describe('voice noise suppression configuration', () => {
expect(second).toEqual(DEFAULT_VOICE_NOISE_SUPPRESSION_CONFIG);
});
test.each([
{},
{enabled: false},
{enabled: undefined},
{suppression_strength: 42},
])('keeps partial updates free of configuration defaults: %j', (patch) => {
expect(VoiceNoiseSuppressionConfigUpdateRequest.parse(patch)).toEqual(patch);
});
test.each([{}, {enabled: false}, {enabled: undefined}, {suppression_strength: 42}])(
'keeps partial updates free of configuration defaults: %j',
(patch) => {
expect(VoiceNoiseSuppressionConfigUpdateRequest.parse(patch)).toEqual(patch);
},
);
test('does not accept a client-provided configuration version', () => {
expect(VoiceNoiseSuppressionConfigUpdateRequest.parse({config_version: 12})).toEqual({});
@@ -371,23 +369,21 @@ describe('resolveVoiceNoiseSuppressionForCall', () => {
{allowUserOverride: true, preference: 'gtcrn', expectedBackend: 'rnnoise', expectedSource: 'canary'},
{allowUserOverride: false, preference: 'speex', expectedBackend: 'rnnoise', expectedSource: 'canary'},
{allowUserOverride: true, preference: null, expectedBackend: 'rnnoise', expectedSource: 'canary'},
] as const)('allow_user_override $allowUserOverride with preference $preference resolves to $expectedSource', ({
allowUserOverride,
preference,
expectedBackend,
expectedSource,
}) => {
const assignment = createAssignment({
backend: 'rnnoise',
source: 'canary',
allow_user_override: allowUserOverride,
enabled_backends: ['none', 'standard', 'speex', 'rnnoise'],
});
expect(resolveVoiceNoiseSuppressionForCall(assignment, null, preference)).toMatchObject({
backend: expectedBackend,
source: expectedSource,
});
});
] as const)(
'allow_user_override $allowUserOverride with preference $preference resolves to $expectedSource',
({allowUserOverride, preference, expectedBackend, expectedSource}) => {
const assignment = createAssignment({
backend: 'rnnoise',
source: 'canary',
allow_user_override: allowUserOverride,
enabled_backends: ['none', 'standard', 'speex', 'rnnoise'],
});
expect(resolveVoiceNoiseSuppressionForCall(assignment, null, preference)).toMatchObject({
backend: expectedBackend,
source: expectedSource,
});
},
);
test('a user override also outranks a guild rule', () => {
const assignment = createAssignment({
@@ -96,20 +96,17 @@ describe('TemplateChannel permission overwrites', () => {
expect(channel.permission_overwrites).toEqual([{id: '2', type: expected, allow: '8', deny: '0'}]);
});
it.each([
'invalid',
'NaN',
'Infinity',
Number.NaN,
Number.POSITIVE_INFINITY,
])('rejects nonfinite overwrite type %j', (type) => {
expect(
TemplateChannel.safeParse({
id: '1',
type: 0,
position: 0,
permission_overwrites: [{id: '2', type, allow: '8', deny: '0'}],
}).success,
).toBe(false);
});
it.each(['invalid', 'NaN', 'Infinity', Number.NaN, Number.POSITIVE_INFINITY])(
'rejects nonfinite overwrite type %j',
(type) => {
expect(
TemplateChannel.safeParse({
id: '1',
type: 0,
position: 0,
permission_overwrites: [{id: '2', type, allow: '8', deny: '0'}],
}).success,
).toBe(false);
},
);
});
@@ -10,17 +10,14 @@ describe('jobs schemas', () => {
expect(JobLedgerEntrySchema.shape.status.safeParse('failed').success).toBe(false);
});
test.each([
'queued',
'running',
'succeeded',
'cancelled',
'deadletter',
])('accepts ledger status %s across query, request, and response', (status) => {
expect(ListJobsQuery.parse({status}).status).toBe(status);
expect(ListJobsRequest.parse({status}).status).toBe(status);
expect(JobLedgerEntrySchema.shape.status.parse(status)).toBe(status);
});
test.each(['queued', 'running', 'succeeded', 'cancelled', 'deadletter'])(
'accepts ledger status %s across query, request, and response',
(status) => {
expect(ListJobsQuery.parse({status}).status).toBe(status);
expect(ListJobsRequest.parse({status}).status).toBe(status);
expect(JobLedgerEntrySchema.shape.status.parse(status)).toBe(status);
},
);
});
describe('job pagination cursor', () => {
@@ -34,16 +31,15 @@ describe('job pagination cursor', () => {
expect(ListJobsQuery.parse(cursor)).toEqual({...cursor, limit: 50, max_lookback_days: 14});
});
test.each([
'cursor_bucket_day',
'cursor_created_at',
'cursor_job_id',
] as const)('rejects a cursor missing %s', (field) => {
expect(ListJobsQuery.safeParse({...cursor, [field]: undefined})).toMatchObject({
success: false,
error: {issues: [{path: [field]}]},
});
});
test.each(['cursor_bucket_day', 'cursor_created_at', 'cursor_job_id'] as const)(
'rejects a cursor missing %s',
(field) => {
expect(ListJobsQuery.safeParse({...cursor, [field]: undefined})).toMatchObject({
success: false,
error: {issues: [{path: [field]}]},
});
},
);
test.each([
{cursor_bucket_day: '2023-02-29'},
@@ -18,16 +18,12 @@ describe('MessageNonceRequest', () => {
expect(MessageNonceRequest.parse(input)).toBe(expected);
});
it.each([
-1,
0.5,
Number.MAX_SAFE_INTEGER + 1,
Number.POSITIVE_INFINITY,
'',
'a'.repeat(33),
])('rejects invalid nonce %j', (input) => {
expect(MessageNonceRequest.safeParse(input).success).toBe(false);
});
it.each([-1, 0.5, Number.MAX_SAFE_INTEGER + 1, Number.POSITIVE_INFINITY, '', 'a'.repeat(33)])(
'rejects invalid nonce %j',
(input) => {
expect(MessageNonceRequest.safeParse(input).success).toBe(false);
},
);
});
describe('MessageRequestSchema', () => {
@@ -137,14 +137,12 @@ describe('application redirect policies', () => {
])('accepts registered URI %s', (uri) => {
expect(ApplicationCreateRequest.parse({name: 'Application', redirect_uris: [uri]}).redirect_uris).toEqual([uri]);
});
it.each([
'http://example.com/callback',
'https://',
'/relative',
'ftp://example.com/callback',
])('rejects registered URI %s', (uri) => {
expect(ApplicationCreateRequest.safeParse({name: 'Application', redirect_uris: [uri]}).success).toBe(false);
});
it.each(['http://example.com/callback', 'https://', '/relative', 'ftp://example.com/callback'])(
'rejects registered URI %s',
(uri) => {
expect(ApplicationCreateRequest.safeParse({name: 'Application', redirect_uris: [uri]}).success).toBe(false);
},
);
it('defaults missing create URIs but does not clear missing update URIs', () => {
expect(ApplicationCreateRequest.parse({name: 'Application'})).toEqual({name: 'Application', redirect_uris: []});
expect(ApplicationUpdateRequest.parse({})).toEqual({});
@@ -71,13 +71,12 @@ describe.each([
{name: 'update body', schema: UpdateVoiceServerRequestBody, required: {}},
{name: 'update service request', schema: UpdateVoiceServerRequest, required: {region_id: 'eu', server_id: 'primary'}},
])('$name coordinates', ({schema, required}) => {
it.each([
{},
{latitude: 0, longitude: 0},
{latitude: null, longitude: null},
])('accepts the paired state %j', (coordinates) => {
expect(schema.parse({...required, ...coordinates})).toMatchObject(coordinates);
});
it.each([{}, {latitude: 0, longitude: 0}, {latitude: null, longitude: null}])(
'accepts the paired state %j',
(coordinates) => {
expect(schema.parse({...required, ...coordinates})).toMatchObject(coordinates);
},
);
it.each([
{latitude: 0},
@@ -163,15 +162,13 @@ describe.each([
expect(schema.parse({})).toEqual(bulkDeleteDefaults);
});
it.each([
'include_dms',
'include_dms_closed',
'include_group_dms',
'include_guilds',
] as const)('accepts %s as the only selected context', (field) => {
const selection = {...noSelectedContexts, [field]: true};
expect(schema.parse(selection)).toEqual({...bulkDeleteDefaults, ...selection});
});
it.each(['include_dms', 'include_dms_closed', 'include_group_dms', 'include_guilds'] as const)(
'accepts %s as the only selected context',
(field) => {
const selection = {...noSelectedContexts, [field]: true};
expect(schema.parse(selection)).toEqual({...bulkDeleteDefaults, ...selection});
},
);
it('does not require selected contexts for inaccessible-only scope', () => {
const selection = {...noSelectedContexts, scope: 'inaccessible_only'};
@@ -5,11 +5,12 @@ import {AuditLogActionTypeSchema} from '@fluxer/schema/src/primitives/AuditLogVa
import {describe, expect, it} from 'vitest';
describe('AuditLogActionTypeSchema', () => {
it.each(
Object.values(AuditLogActionType).filter((value) => typeof value === 'number'),
)('accepts registered action %i', (value) => {
expect(AuditLogActionTypeSchema.parse(value)).toBe(value);
});
it.each(Object.values(AuditLogActionType).filter((value) => typeof value === 'number'))(
'accepts registered action %i',
(value) => {
expect(AuditLogActionTypeSchema.parse(value)).toBe(value);
},
);
it.each([0, 9, 999, -1, 1.5, '1', 'GUILD_UPDATE', null])('rejects unknown or nonnumeric action %j', (value) => {
expect(AuditLogActionTypeSchema.safeParse(value).success).toBe(false);
@@ -53,21 +53,12 @@ describe('isValidBase64', () => {
expect(isValidBase64(input)).toBe(true);
});
it.each([
'YQ',
'YQ=',
'YQ===',
'====',
'Y=Q=',
'YR==',
'YWJ=',
'YWJ_',
'YWJ-',
'YW J',
'éAAA',
])('rejects malformed or noncanonical encoding %j', (input) => {
expect(isValidBase64(input)).toBe(false);
});
it.each(['YQ', 'YQ=', 'YQ===', '====', 'Y=Q=', 'YR==', 'YWJ=', 'YWJ_', 'YWJ-', 'YW J', 'éAAA'])(
'rejects malformed or noncanonical encoding %j',
(input) => {
expect(isValidBase64(input)).toBe(false);
},
);
it.each([1, 2, 3, 255, 256])('accepts a byte round trip of length %i', (length) => {
const bytes = Buffer.from(Array.from({length}, (_, index) => index % 256));
@@ -137,13 +128,13 @@ describe('base64LengthForBytes', () => {
expect(base64LengthForBytes(bytes) % 4).toBe(0);
});
it.each([
EMOJI_MAX_SIZE,
EMOJI_MAX_SIZE + 1,
])('accepts %i encoded bytes; decoded-byte limits remain authoritative', (bytes) => {
const schema = createBase64StringType(1, base64LengthForBytes(EMOJI_MAX_SIZE));
const encoded = Buffer.alloc(bytes, 1).toString('base64');
expect(encoded.length).toBe(base64LengthForBytes(EMOJI_MAX_SIZE));
expect(schema.parse(encoded)).toBe(encoded);
});
it.each([EMOJI_MAX_SIZE, EMOJI_MAX_SIZE + 1])(
'accepts %i encoded bytes; decoded-byte limits remain authoritative',
(bytes) => {
const schema = createBase64StringType(1, base64LengthForBytes(EMOJI_MAX_SIZE));
const encoded = Buffer.alloc(bytes, 1).toString('base64');
expect(encoded.length).toBe(base64LengthForBytes(EMOJI_MAX_SIZE));
expect(schema.parse(encoded)).toBe(encoded);
},
);
});
@@ -50,10 +50,9 @@ it.each([1, 2])('rejects legacy NSFW level %i', (value) => {
expect(NSFWLevelSchema.safeParse(value).success).toBe(false);
});
it.each([
MessageNotifications.NULL,
MessageNotifications.NO_MESSAGES,
MessageNotifications.INHERIT,
])('rejects channel-only notification setting %i as a guild default', (value) => {
expect(DefaultMessageNotificationsSchema.safeParse(value).success).toBe(false);
});
it.each([MessageNotifications.NULL, MessageNotifications.NO_MESSAGES, MessageNotifications.INHERIT])(
'rejects channel-only notification setting %i as a guild default',
(value) => {
expect(DefaultMessageNotificationsSchema.safeParse(value).success).toBe(false);
},
);
@@ -5,11 +5,12 @@ import {MessageReferenceTypeSchema, MessageTypeSchema} from '@fluxer/schema/src/
import {describe, expect, it} from 'vitest';
describe('MessageTypeSchema', () => {
it.each(
Object.values(MessageTypes).filter((value) => value !== MessageTypes.CLIENT_SYSTEM),
)('accepts wire message type %i', (value) => {
expect(MessageTypeSchema.parse(value)).toBe(value);
});
it.each(Object.values(MessageTypes).filter((value) => value !== MessageTypes.CLIENT_SYSTEM))(
'accepts wire message type %i',
(value) => {
expect(MessageTypeSchema.parse(value)).toBe(value);
},
);
it.each([MessageTypes.CLIENT_SYSTEM, 8, -1, 0.5, '0', null])('rejects non-wire message type %j', (value) => {
expect(MessageTypeSchema.safeParse(value).success).toBe(false);
@@ -40,24 +40,15 @@ describe('createQueryIntegerType', () => {
expect(schema.parse(input)).toBe(expected);
});
it.each([
'3.14',
'3.0',
'42px',
'1e2',
'0x10',
'',
' ',
'NaN',
'Infinity',
'-1',
'2147483648',
])('rejects %j without truncation or coercion', (input) => {
expect(schema.safeParse(input)).toMatchObject({
success: false,
error: {issues: [{message: ValidationErrorCodes.VALUE_MUST_BE_INTEGER_IN_RANGE}]},
});
});
it.each(['3.14', '3.0', '42px', '1e2', '0x10', '', ' ', 'NaN', 'Infinity', '-1', '2147483648'])(
'rejects %j without truncation or coercion',
(input) => {
expect(schema.safeParse(input)).toMatchObject({
success: false,
error: {issues: [{message: ValidationErrorCodes.VALUE_MUST_BE_INTEGER_IN_RANGE}]},
});
},
);
it.each(['-5', '5'])('accepts the configured range boundary %s', (input) => {
expect(createQueryIntegerType({minValue: -5, maxValue: 5}).parse(input)).toBe(Number(input));
@@ -64,14 +64,12 @@ describe('Int64Type', () => {
});
});
it.each([
Number.MAX_SAFE_INTEGER + 1,
Number.NaN,
Number.POSITIVE_INFINITY,
1.5,
])('rejects lossy or noninteger numeric input %j', (input) => {
expect(Int64Type.safeParse(input).success).toBe(false);
});
it.each([Number.MAX_SAFE_INTEGER + 1, Number.NaN, Number.POSITIVE_INFINITY, 1.5])(
'rejects lossy or noninteger numeric input %j',
(input) => {
expect(Int64Type.safeParse(input).success).toBe(false);
},
);
});
describe('Int64StringType', () => {
@@ -92,14 +90,12 @@ describe('UnsignedInt64Type', () => {
expect(UnsignedInt64Type.parse(input)).toBe(expected);
});
it.each([
'-1',
'+1',
'9223372036854775808',
'18446744073709551615',
])('rejects %s outside unsigned signed-64-bit storage', (input) => {
expect(UnsignedInt64Type.safeParse(input).success).toBe(false);
});
it.each(['-1', '+1', '9223372036854775808', '18446744073709551615'])(
'rejects %s outside unsigned signed-64-bit storage',
(input) => {
expect(UnsignedInt64Type.safeParse(input).success).toBe(false);
},
);
});
describe('SnowflakeType', () => {
+1
View File
@@ -2,6 +2,7 @@
"extends": "../../tsconfigs/base.json",
"compilerOptions": {
"lib": ["ESNext", "DOM"],
"types": ["node"],
"paths": {
"@fluxer/*": ["./../../packages/*"]
}
+2 -2
View File
@@ -13,7 +13,7 @@
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@fluxer/constants": "workspace:*",
@@ -21,7 +21,7 @@
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
+2 -2
View File
@@ -20,11 +20,11 @@
"bench": "vitest bench --run",
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsgo --noEmit"
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"typescript": "catalog:ts7",
"vitest": "catalog:"
}
}
@@ -16,7 +16,7 @@ import type {
VoiceEngineV2ScreenOptions,
VoiceEngineV2Stats,
} from '@fluxer/voice_engine_v2/src/protocol/types';
import {bench, describe} from 'vitest';
import {test} from 'vitest';
interface VoiceEngineV2BenchFixture {
events: Array<VoiceEngineV2Event>;
@@ -100,28 +100,28 @@ const participantEvent: VoiceEngineV2Event = {
const statsPayload: VoiceEngineV2Stats = Object.freeze({rttMs: 42, outbound: [], inbound: []});
const statsEvent: VoiceEngineV2Event = {type: 'stats.collected', operationId: 9_999_999, stats: statsPayload};
describe('voice engine v2 reducer hot paths', () => {
bench('inboundVideo.frameReceived', () => {
test('voice engine v2 reducer hot paths', async ({bench}) => {
await bench('inboundVideo.frameReceived', () => {
transitionVoiceEngineV2(connectedSnapshot, frameEvent);
});
}).run();
bench('inboundVideo.frameStats', () => {
await bench('inboundVideo.frameStats', () => {
transitionVoiceEngineV2(connectedSnapshot, frameStatsEvent);
});
}).run();
bench('microphone.publishRequested', () => {
await bench('microphone.publishRequested', () => {
transitionVoiceEngineV2(connectedSnapshot, microphoneEvent);
});
}).run();
bench('screen.publishRequested', () => {
await bench('screen.publishRequested', () => {
transitionVoiceEngineV2(connectedSnapshot, screenEvent);
});
}).run();
bench('room.participantJoined', () => {
await bench('room.participantJoined', () => {
transitionVoiceEngineV2(connectedSnapshot, participantEvent);
});
}).run();
bench('stats.collected', () => {
await bench('stats.collected', () => {
transitionVoiceEngineV2(connectedSnapshot, statsEvent);
});
}).run();
});
@@ -98,87 +98,88 @@ interface VoiceTrackClassificationFixture {
}
describe('voice engine v2 policies', () => {
it.each(
microphoneFailureFixtures as Array<MicrophoneFailureFixture>,
)('replays microphone failure action fixture: $name', ({result, requestedEnabled, context, expected}) => {
expect(getVoiceEngineV2MicrophoneOperationFailureAction(result, requestedEnabled, context)).toBe(expected);
});
it.each(microphoneFailureFixtures as Array<MicrophoneFailureFixture>)(
'replays microphone failure action fixture: $name',
({result, requestedEnabled, context, expected}) => {
expect(getVoiceEngineV2MicrophoneOperationFailureAction(result, requestedEnabled, context)).toBe(expected);
},
);
it.each(
hardwareEncoderCapabilityFixtures as Array<HardwareEncoderCapabilityFixture>,
)('replays hardware encoder capability fixture: $name', ({
input,
codec,
expectedCapabilities,
expectedNativeNvenc,
}) => {
const capabilities = normalizeVoiceEngineV2HardwareEncoderCapabilities(input);
expect(capabilities).toMatchObject(expectedCapabilities);
expect(hasVoiceEngineV2NativeNvencEncoder(capabilities, codec)).toBe(expectedNativeNvenc);
});
it.each(hardwareEncoderCapabilityFixtures as Array<HardwareEncoderCapabilityFixture>)(
'replays hardware encoder capability fixture: $name',
({input, codec, expectedCapabilities, expectedNativeNvenc}) => {
const capabilities = normalizeVoiceEngineV2HardwareEncoderCapabilities(input);
expect(capabilities).toMatchObject(expectedCapabilities);
expect(hasVoiceEngineV2NativeNvencEncoder(capabilities, codec)).toBe(expectedNativeNvenc);
},
);
it.each(
screenShareEncodingPlanFixtures as Array<ScreenShareEncodingPlanFixture>,
)('replays screen-share encoding plan fixture: $name', (fixture) => {
const plan = planVoiceEngineV2ScreenEncodingChange(fixture.input);
expect(plan.action).toBe(fixture.expectedAction);
expect(plan.reason).toBe(fixture.expectedReason);
if (fixture.expectedCodec !== undefined) {
expect(plan.desired?.codec).toBe(fixture.expectedCodec);
}
if (fixture.expectedHardwareEncoding !== undefined) {
expect(plan.desired?.hardwareEncoding).toBe(fixture.expectedHardwareEncoding);
}
if (fixture.expectedZeroCopyRequired !== undefined) {
expect(plan.desired?.zeroCopyRequired).toBe(fixture.expectedZeroCopyRequired);
}
if (fixture.expectedErrorCode !== undefined) {
expect(plan.error?.code).toBe(fixture.expectedErrorCode);
}
});
it.each(screenShareEncodingPlanFixtures as Array<ScreenShareEncodingPlanFixture>)(
'replays screen-share encoding plan fixture: $name',
(fixture) => {
const plan = planVoiceEngineV2ScreenEncodingChange(fixture.input);
expect(plan.action).toBe(fixture.expectedAction);
expect(plan.reason).toBe(fixture.expectedReason);
if (fixture.expectedCodec !== undefined) {
expect(plan.desired?.codec).toBe(fixture.expectedCodec);
}
if (fixture.expectedHardwareEncoding !== undefined) {
expect(plan.desired?.hardwareEncoding).toBe(fixture.expectedHardwareEncoding);
}
if (fixture.expectedZeroCopyRequired !== undefined) {
expect(plan.desired?.zeroCopyRequired).toBe(fixture.expectedZeroCopyRequired);
}
if (fixture.expectedErrorCode !== undefined) {
expect(plan.error?.code).toBe(fixture.expectedErrorCode);
}
},
);
it.each(
cameraShareEncodingPlanFixtures as Array<CameraShareEncodingPlanFixture>,
)('replays camera-share encoding plan fixture: $name', (fixture) => {
const plan = planVoiceEngineV2CameraEncodingChange(fixture.input);
expect(plan.action).toBe(fixture.expectedAction);
expect(plan.reason).toBe(fixture.expectedReason);
if (fixture.expectedCodec !== undefined) {
expect(plan.desired?.codec).toBe(fixture.expectedCodec);
}
if (fixture.expectedMirror !== undefined) {
expect(plan.desired?.mirror).toBe(fixture.expectedMirror);
}
if (fixture.expectedBackgroundMode !== undefined) {
expect(plan.desired?.backgroundMode).toBe(fixture.expectedBackgroundMode);
}
if (fixture.expectedWidth !== undefined) {
expect(plan.desired?.width).toBe(fixture.expectedWidth);
}
if (fixture.expectedFrameRate !== undefined) {
expect(plan.desired?.frameRate).toBe(fixture.expectedFrameRate);
}
if (fixture.expectedErrorCode !== undefined) {
expect(plan.error?.code).toBe(fixture.expectedErrorCode);
}
});
it.each(cameraShareEncodingPlanFixtures as Array<CameraShareEncodingPlanFixture>)(
'replays camera-share encoding plan fixture: $name',
(fixture) => {
const plan = planVoiceEngineV2CameraEncodingChange(fixture.input);
expect(plan.action).toBe(fixture.expectedAction);
expect(plan.reason).toBe(fixture.expectedReason);
if (fixture.expectedCodec !== undefined) {
expect(plan.desired?.codec).toBe(fixture.expectedCodec);
}
if (fixture.expectedMirror !== undefined) {
expect(plan.desired?.mirror).toBe(fixture.expectedMirror);
}
if (fixture.expectedBackgroundMode !== undefined) {
expect(plan.desired?.backgroundMode).toBe(fixture.expectedBackgroundMode);
}
if (fixture.expectedWidth !== undefined) {
expect(plan.desired?.width).toBe(fixture.expectedWidth);
}
if (fixture.expectedFrameRate !== undefined) {
expect(plan.desired?.frameRate).toBe(fixture.expectedFrameRate);
}
if (fixture.expectedErrorCode !== undefined) {
expect(plan.error?.code).toBe(fixture.expectedErrorCode);
}
},
);
it.each(
voiceStatsCoercionFixtures as Array<VoiceStatsCoercionFixture>,
)('replays voice stats coercion fixture: $name', ({input, expected}) => {
expect(coerceVoiceEngineV2Stats(input)).toMatchObject(expected);
});
it.each(voiceStatsCoercionFixtures as Array<VoiceStatsCoercionFixture>)(
'replays voice stats coercion fixture: $name',
({input, expected}) => {
expect(coerceVoiceEngineV2Stats(input)).toMatchObject(expected);
},
);
it.each(voiceStatsSummaryFixtures as Array<VoiceStatsSummaryFixture>)('replays voice stats summary fixture: $name', ({
input,
expectedSummary,
}) => {
expect(summarizeVoiceEngineV2Stats(input)).toMatchObject(expectedSummary);
});
it.each(voiceStatsSummaryFixtures as Array<VoiceStatsSummaryFixture>)(
'replays voice stats summary fixture: $name',
({input, expectedSummary}) => {
expect(summarizeVoiceEngineV2Stats(input)).toMatchObject(expectedSummary);
},
);
it.each(
voiceTrackClassificationFixtures as Array<VoiceTrackClassificationFixture>,
)('replays voice track classification fixture: $name', ({input, expected}) => {
expect(classifyVoiceEngineV2TrackStats(input)).toEqual(expected);
});
it.each(voiceTrackClassificationFixtures as Array<VoiceTrackClassificationFixture>)(
'replays voice track classification fixture: $name',
({input, expected}) => {
expect(classifyVoiceEngineV2TrackStats(input)).toEqual(expected);
},
);
});
@@ -18,7 +18,7 @@ import type {
} from '@fluxer/voice_engine_v2/src/protocol/types';
import {createVoiceEngineV2MemoryEventLogSpillSink} from '@fluxer/voice_engine_v2/src/runtime/eventLogRing';
import {VoiceEngineV2Runtime} from '@fluxer/voice_engine_v2/src/runtime/VoiceEngineV2Runtime';
import {bench, describe} from 'vitest';
import {test} from 'vitest';
interface VoiceEngineV2BenchFixture {
events: Array<VoiceEngineV2Event>;
@@ -108,24 +108,24 @@ const runtimeForScreen = buildRuntimeWithConnectedSession();
const runtimeForParticipant = buildRuntimeWithConnectedSession();
const runtimeForStats = buildRuntimeWithConnectedSession();
describe('voice engine v2 runtime dispatch round-trip', () => {
bench('dispatch inboundVideo.frameReceived', () => {
test('voice engine v2 runtime dispatch round-trip', async ({bench}) => {
await bench('dispatch inboundVideo.frameReceived', () => {
runtimeForFrames.dispatch(frameEvent);
});
}).run();
bench('dispatch microphone.publishRequested', () => {
await bench('dispatch microphone.publishRequested', () => {
runtimeForMicrophone.dispatch(microphoneEvent);
});
}).run();
bench('dispatch screen.publishRequested', () => {
await bench('dispatch screen.publishRequested', () => {
runtimeForScreen.dispatch(screenEvent);
});
}).run();
bench('dispatch room.participantJoined', () => {
await bench('dispatch room.participantJoined', () => {
runtimeForParticipant.dispatch(participantEvent);
});
}).run();
bench('dispatch stats.collected', () => {
await bench('dispatch stats.collected', () => {
runtimeForStats.dispatch(statsEvent);
});
}).run();
});
@@ -10,7 +10,7 @@ import type {
VoiceEngineV2Track,
VoiceEngineV2TrackSource,
} from '@fluxer/voice_engine_v2/src/protocol/types';
import {bench, describe} from 'vitest';
import {test} from 'vitest';
const PARTICIPANT_COUNT = 8;
const TRACKS_PER_PARTICIPANT = 4;
@@ -56,16 +56,16 @@ function buildRealisticSnapshot(): VoiceEngineV2Snapshot {
const realisticSnapshot = buildRealisticSnapshot();
const serializedSnapshot = JSON.stringify(realisticSnapshot);
describe('voice engine v2 snapshot serialise/deserialise baseline', () => {
bench('JSON.stringify snapshot (8 participants × 4 tracks)', () => {
test('voice engine v2 snapshot serialise/deserialise baseline', async ({bench}) => {
await bench('JSON.stringify snapshot (8 participants × 4 tracks)', () => {
JSON.stringify(realisticSnapshot);
});
}).run();
bench('JSON.parse snapshot (8 participants × 4 tracks)', () => {
await bench('JSON.parse snapshot (8 participants × 4 tracks)', () => {
JSON.parse(serializedSnapshot);
});
}).run();
bench('JSON.stringify + JSON.parse round-trip', () => {
await bench('JSON.stringify + JSON.parse round-trip', () => {
JSON.parse(JSON.stringify(realisticSnapshot));
});
}).run();
});
@@ -12,7 +12,6 @@ export default defineConfig({
benchmark: {
include: ['**/*.bench.{ts,tsx}'],
exclude: ['node_modules', 'dist'],
reporters: ['default'],
},
},
});