diff --git a/.oxlintrc.json b/.oxlintrc.json index 02d89b34cc8..988d6635141 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -34,6 +34,7 @@ "typescript/await-thenable": "error", "typescript/no-floating-promises": "error", "typescript/no-misused-promises": "error", + "typescript/no-misused-spread": "error", "typescript/no-unsafe-enum-comparison": "error", "typescript/no-unsafe-unary-minus": "error", "typescript/no-duplicate-type-constituents": "error", @@ -66,7 +67,10 @@ "typescript/no-unsafe-assignment": "off", "typescript/no-unsafe-call": "off", "typescript/no-unsafe-member-access": "off", - "typescript/no-unsafe-return": "off" + "typescript/no-unsafe-return": "off", + + "vitest/no-conditional-tests": "error", + "vitest/hoisted-apis-on-top": "error" }, "overrides": [ { diff --git a/lib/config/options/index.spec.ts b/lib/config/options/index.spec.ts index 692f4587b62..e080dd6e26e 100644 --- a/lib/config/options/index.spec.ts +++ b/lib/config/options/index.spec.ts @@ -51,19 +51,19 @@ describe('config/options/index', () => { describe('every option with allowedValues and a default must have the default in allowedValues', () => { const opts = getOptions(); - for (const option of opts) { - if (option.allowedValues && !isNullOrUndefined(option.default)) { - it(`${option.name}: \`${option.default}\` is in ${JSON.stringify(option.allowedValues)}`, () => { - expect(option.allowedValues).toBeDefined(); + for (const option of opts.filter( + (o) => o.allowedValues && !isNullOrUndefined(o.default), + )) { + it(`${option.name}: \`${option.default}\` is in ${JSON.stringify(option.allowedValues)}`, () => { + expect(option.allowedValues).toBeDefined(); - const defaults = Array.isArray(option.default) - ? option.default - : [option.default]; - for (const defVal of defaults) { - expect(option.allowedValues).toContain(defVal); - } - }); - } + const defaults = Array.isArray(option.default) + ? option.default + : [option.default]; + for (const defVal of defaults) { + expect(option.allowedValues).toContain(defVal); + } + }); } }); @@ -71,20 +71,19 @@ describe('config/options/index', () => { const opts = getOptions(); const optionNames = new Set(opts.map((o) => o.name)); - for (const option of opts) { - if (option.requiredIf) { - for (const req of option.requiredIf) { - for (const prop of req.siblingProperties) { - it(`${option.name}'s reference to ${prop.property} is valid`, () => { - expect(optionNames).toContain(prop.property); - }); + for (const option of opts.filter((o) => o.requiredIf)) { + for (const req of option.requiredIf!) { + for (const prop of req.siblingProperties) { + it(`${option.name}'s reference to ${prop.property} is valid`, () => { + expect(optionNames).toContain(prop.property); + }); - const foundOption = opts.filter((o) => o.name === prop.property); - if (foundOption?.length && foundOption[0].allowedValues) { - it(`${option.name}'s value for ${prop.property} is valid, according to allowedValues`, () => { - expect(foundOption[0].allowedValues).toContain(prop.value); - }); - } + const foundOption = opts.filter((o) => o.name === prop.property); + // oxlint-disable-next-line vitest/no-conditional-tests -- TODO: fix me + if (foundOption?.length && foundOption[0].allowedValues) { + it(`${option.name}'s value for ${prop.property} is valid, according to allowedValues`, () => { + expect(foundOption[0].allowedValues).toContain(prop.value); + }); } } } diff --git a/lib/config/presets/internal/index.spec.ts b/lib/config/presets/internal/index.spec.ts index fa89114692e..f1372ec5712 100644 --- a/lib/config/presets/internal/index.spec.ts +++ b/lib/config/presets/internal/index.spec.ts @@ -27,26 +27,29 @@ describe('config/presets/internal/index', () => { }); for (const [groupName, groupPresets] of Object.entries(internal.groups)) { - for (const [presetName, presetConfig] of Object.entries(groupPresets)) { - const preset = `${groupName}:${presetName}`; - if (presetName !== 'description' && !ignoredPresets.includes(preset)) { - it(`${preset} validates`, async () => { - try { - const { config } = await resolveConfigPresets( - massageConfig(presetConfig), - ); - const configType = groupName === 'global' ? 'global' : 'repo'; - const res = await validateConfig(configType, config, true); - expect(res.errors).toHaveLength(0); - expect(res.warnings).toHaveLength(0); - } catch (err) { - if (err.validationError) { - throw new Error(err.validationError); - } - throw err; + for (const [presetName, presetConfig] of Object.entries( + groupPresets, + ).filter( + ([key]) => + key !== 'description' && + !ignoredPresets.includes(`${groupName}:${key}`), + )) { + it(`${`${groupName}:${presetName}`} validates`, async () => { + try { + const { config } = await resolveConfigPresets( + massageConfig(presetConfig), + ); + const configType = groupName === 'global' ? 'global' : 'repo'; + const res = await validateConfig(configType, config, true); + expect(res.errors).toHaveLength(0); + expect(res.warnings).toHaveLength(0); + } catch (err) { + if (err.validationError) { + throw new Error(err.validationError); } - }); - } + throw err; + } + }); } } diff --git a/lib/logger/utils.ts b/lib/logger/utils.ts index b6b5a90313c..ce903a44662 100644 --- a/lib/logger/utils.ts +++ b/lib/logger/utils.ts @@ -95,6 +95,8 @@ export default function prepareError(err: Error): Record { } const response: Record = { + // We want to loose class information, but keep enumerable properties of the error + // oxlint-disable-next-line typescript/no-misused-spread ...err, }; diff --git a/lib/modules/manager/gradle/extract/consistent-versions-plugin.ts b/lib/modules/manager/gradle/extract/consistent-versions-plugin.ts index 32b8d8ce3ee..5f5ff3d1cdc 100644 --- a/lib/modules/manager/gradle/extract/consistent-versions-plugin.ts +++ b/lib/modules/manager/gradle/extract/consistent-versions-plugin.ts @@ -209,5 +209,10 @@ export function parsePropsFile( logger.trace( `Found ${depVerExactMap.size} dependencies and ${depVerRegexMap.size} wildcard dependencies in ${VERSIONS_PROPS}.`, ); - return [depVerExactMap, new Map([...depVerRegexMap].sort().reverse())]; + return [ + depVerExactMap, + new Map( + [...depVerRegexMap].sort(([ka], [kb]) => ka.localeCompare(kb)).reverse(), + ), + ]; } diff --git a/lib/modules/manager/index.spec.ts b/lib/modules/manager/index.spec.ts index a4773c6df81..6bd8e5c5080 100644 --- a/lib/modules/manager/index.spec.ts +++ b/lib/modules/manager/index.spec.ts @@ -25,12 +25,12 @@ describe('modules/manager/index', () => { }); describe('lockFileNames', () => { - for (const [name, mgr] of manager.getManagers()) { - if (mgr.supportsLockFileMaintenance) { - it(`has lockFileNames for ${name}`, () => { - expect(mgr.lockFileNames).toBeNonEmptyArray(); - }); - } + for (const [name, mgr] of [...manager.getManagers()].filter( + ([_, mgr]) => mgr.supportsLockFileMaintenance, + )) { + it(`has lockFileNames for ${name}`, () => { + expect(mgr.lockFileNames).toBeNonEmptyArray(); + }); } }); diff --git a/lib/modules/manager/mise/extract.ts b/lib/modules/manager/mise/extract.ts index 42423ac46b5..e2d3b4b7970 100644 --- a/lib/modules/manager/mise/extract.ts +++ b/lib/modules/manager/mise/extract.ts @@ -8,7 +8,7 @@ import { } from '@sindresorhus/is'; import { logger } from '../../../logger/index.ts'; import { regEx } from '../../../util/regex.ts'; -import type { ToolingConfig } from '../asdf/upgradeable-tooling.ts'; +import type { StaticTooling } from '../asdf/upgradeable-tooling.ts'; import type { PackageDependency, PackageFileContent } from '../types.ts'; import type { BackendToolingConfig } from './backends.ts'; import { @@ -111,7 +111,7 @@ function getToolConfig( toolName: string, version: string, toolOptions: MiseToolOptions, -): ToolingConfig | BackendToolingConfig | null { +): StaticTooling | BackendToolingConfig | null { switch (backend) { case '': // If the tool name does not specify a backend, it should be a short name or an alias defined by users @@ -160,7 +160,7 @@ function getToolConfig( function getRegistryToolConfig( short: string, version: string, -): ToolingConfig | null { +): StaticTooling | null { // Try to get the config from miseTooling first, then asdfTooling return ( getConfigFromTooling(miseTooling, short, version) ?? @@ -172,7 +172,7 @@ function getConfigFromTooling( toolingSource: Record, name: string, version: string, -): ToolingConfig | null { +): StaticTooling | null { const toolDefinition = toolingSource[name]; if (!toolDefinition) { return null; @@ -188,7 +188,7 @@ function getConfigFromTooling( function createDependency( name: string, version: string | null, - config: ToolingConfig | BackendToolingConfig | null, + config: StaticTooling | BackendToolingConfig | null, ): PackageDependency { if (version === null) { return {