chore(lint): switch rules from jest to vitest (#5470)

* chore(lint): switch rules from jest to vitest

* Revert tsconfig

* Update active-directory
This commit is contained in:
Marc Bernard
2025-11-10 17:00:04 -05:00
committed by GitHub
parent 6c0f9f9ba0
commit b24f513b92
26 changed files with 1314 additions and 909 deletions

View File

@@ -0,0 +1,13 @@
---
'@verdaccio/local-storage': patch
'@verdaccio/ui-theme': patch
'verdaccio-memory': patch
'@verdaccio/ui-components': patch
'@verdaccio/eslint-config': patch
'@verdaccio/middleware': patch
'@verdaccio/config': patch
'@verdaccio/store': patch
'@verdaccio/api': patch
---
chore(lint): switch rules from jest to vitest

View File

@@ -19,3 +19,5 @@ yarn.js
packages/ui-components/storybook-static
dist.js
bundle.js
# generator templates
packages/tools/generator-verdaccio-plugin/generators/app/**

View File

@@ -1,4 +1,3 @@
/* eslint-disable jest/no-commented-out-tests */
import nock from 'nock';
import { describe, expect, test } from 'vitest';

View File

@@ -5,8 +5,8 @@ import { HEADERS, HEADER_TYPE, HTTP_STATUS, TOKEN_BEARER } from '@verdaccio/core
import { buildToken, createUser, initializeServer } from './_helper';
describe('profile ', () => {
describe('get profile ', () => {
describe('profile', () => {
describe('get profile', () => {
test('should return Unauthorized if header token is missing', async () => {
const app = await initializeServer('profile.yaml');
return supertest(app)
@@ -26,7 +26,7 @@ describe('profile ', () => {
.expect(HTTP_STATUS.OK);
});
});
describe('post profile ', () => {
describe('post profile', () => {
test('should return Unauthorized if header token is missing', async () => {
const app = await initializeServer('profile.yaml');
return supertest(app)

View File

@@ -137,7 +137,6 @@ describe('checkSecretKey', () => {
const config = new Config(parseConfigFile(resolveConf('default')), {
forceMigrateToSecureLegacySignature: false,
});
// eslint-disable-next-line jest/no-standalone-expect
expect(() =>
// 64 characters secret long
config.checkSecretKey('b4982dbb0108531fafb552374d7e83724b6458a2b3ffa97ad0edb899bdaefc4a')
@@ -149,7 +148,6 @@ describe('checkSecretKey', () => {
forceMigrateToSecureLegacySignature: false,
});
config.security.api.migrateToSecureLegacySignature = true;
// eslint-disable-next-line jest/no-standalone-expect
expect(
config.checkSecretKey('b4982dbb0108531fafb552374d7e83724b6458a2b3ffa97ad0edb899bdaefc4a')
).toHaveLength(TOKEN_VALID_LENGTH);
@@ -161,7 +159,6 @@ describe('checkSecretKey', () => {
const config = new Config(parseConfigFile(resolveConf('default')));
config.security.api.migrateToSecureLegacySignature = false;
// 64 characters secret long
// eslint-disable-next-line jest/no-standalone-expect
expect(
config.checkSecretKey('b4982dbb0108531fafb552374d7e83724b6458a2b3ffa97ad0edb899bdaefc4a')
).toHaveLength(64);
@@ -172,17 +169,16 @@ describe('checkSecretKey', () => {
const config = new Config(parseConfigFile(resolveConf('default')));
config.security.api.migrateToSecureLegacySignature = true;
// 64 characters secret long
// eslint-disable-next-line jest/no-standalone-expect
expect(
config.checkSecretKey('b4982dbb0108531fafb552374d7e83724b6458a2b3ffa97ad0edb899bdaefc4a')
).toHaveLength(TOKEN_VALID_LENGTH);
});
test.todo('test emit warning with secret key');
test.todo('emit warning with secret key');
});
describe('getMatchedPackagesSpec', () => {
test('should match with react as defined in config file', () => {
test('should match with react as defined in config file - react', () => {
const configParsed = parseConfigFile(parseConfigurationFile('config-getMatchedPackagesSpec'));
const config = new Config(configParsed);
expect(config.getMatchedPackagesSpec('react')).toEqual({
@@ -193,7 +189,7 @@ describe('getMatchedPackagesSpec', () => {
});
});
test('should not match with react as defined in config file', () => {
test('should not match with react as defined in config file - somePackage', () => {
const configParsed = parseConfigFile(parseConfigurationFile('config-getMatchedPackagesSpec'));
const config = new Config(configParsed);
expect(config.getMatchedPackagesSpec('somePackage')).toEqual({

View File

@@ -12,7 +12,7 @@ describe('getConfigParsed', () => {
expect(config).toBeDefined();
});
test('parses config from a YAML file path', () => {
test('parses config from JSON', () => {
const yamlFile = path.join(partialsDir, 'config-getMatchedPackagesSpec.yaml');
const config = getConfigParsed(parseConfigFile(yamlFile));
expect(config).toBeDefined();

View File

@@ -65,7 +65,7 @@ describe('packages requests', () => {
expect(res.status).toEqual(HTTP_STATUS.OK);
});
test('scoped package with encoded @ and path ', async () => {
test('scoped package with encoded @ and path', async () => {
const res = await request(app).get('/%40scope%2ffoo');
expect(res.body).toEqual({ package: '@scope/foo' });
expect(res.status).toEqual(HTTP_STATUS.OK);

View File

@@ -1,14 +1,16 @@
import { vi } from 'vitest';
import { Logger } from '@verdaccio/types';
const logger: Logger = {
warn: jest.fn(),
error: jest.fn(),
fatal: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
child: jest.fn(),
http: jest.fn(),
trace: jest.fn(),
warn: vi.fn(),
error: vi.fn(),
fatal: vi.fn(),
info: vi.fn(),
debug: vi.fn(),
child: vi.fn(),
http: vi.fn(),
trace: vi.fn(),
};
export default logger;

View File

@@ -1,9 +1,9 @@
import ActiveDirectory from 'activedirectory2';
import { vi } from 'vitest';
import { HTTP_STATUS } from '@verdaccio/core';
import ActiveDirectoryPlugin, { NotAuthMessage } from '../src/active-directory';
// eslint-disable-next-line jest/no-mocks-import
import logger from './__mocks__/Logger';
describe('Active Directory Plugin', () => {
@@ -34,12 +34,12 @@ describe('Active Directory Plugin', () => {
});
beforeEach(() => {
jest.resetModules();
vi.resetModules();
});
test('get error when connection fails', (done) => {
const errorMessage = 'Unknown error';
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(errorMessage, undefined));
ActiveDirectory.prototype.authenticate = vi.fn((_1, _2, cb) => cb(errorMessage, undefined));
adPlugin.authenticate('', '', (error, authUser) => {
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
@@ -52,7 +52,7 @@ describe('Active Directory Plugin', () => {
});
test('get error when not authenticated satisfactory', (done) => {
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, false));
ActiveDirectory.prototype.authenticate = vi.fn((_1, _2, cb) => cb(null, false));
adPlugin.authenticate('', '', (error, authUser) => {
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
@@ -68,7 +68,7 @@ describe('Active Directory Plugin', () => {
const user = 'user';
const password = 'password';
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.authenticate = vi.fn((_1, _2, cb) => cb(null, true));
adPlugin.authenticate(user, password, (error, authUser) => {
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
@@ -81,10 +81,10 @@ describe('Active Directory Plugin', () => {
test('get error when getting groups for user', (done) => {
const errorMessage = 'Unknown error retrieving groups';
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
ActiveDirectory.prototype.authenticate = vi.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.getGroupMembershipForUser = vi.fn((_, cb) =>
cb(errorMessage as unknown as object, null)
) as jest.Mock;
);
adPluginSingleGroup.authenticate('', '', (error, authUser) => {
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
@@ -101,10 +101,10 @@ describe('Active Directory Plugin', () => {
const user = 'user';
const password = 'password';
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
ActiveDirectory.prototype.authenticate = vi.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.getGroupMembershipForUser = vi.fn((_, cb) =>
cb(null, [{ cn: 'notMatchGroup' }])
) as jest.Mock;
);
adPluginSingleGroup.authenticate(user, password, (error, authUser) => {
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
@@ -124,10 +124,10 @@ describe('Active Directory Plugin', () => {
const user = 'user';
const password = 'password';
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
ActiveDirectory.prototype.authenticate = vi.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.getGroupMembershipForUser = vi.fn((_, cb) =>
cb(null, [{ cn: groupName }])
) as jest.Mock;
);
adPluginSingleGroup.authenticate(user, password, (error, authUser) => {
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();
@@ -144,10 +144,10 @@ describe('Active Directory Plugin', () => {
const user = 'user';
const password = 'password';
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
ActiveDirectory.prototype.authenticate = vi.fn((_1, _2, cb) => cb(null, true));
ActiveDirectory.prototype.getGroupMembershipForUser = vi.fn((_, cb) =>
cb(null, [{ cn: group2 }, { dn: group3 }])
) as jest.Mock;
);
adPluginMultiGroups.authenticate(user, password, (error, authUser) => {
expect(ActiveDirectory.prototype.authenticate).toHaveBeenCalled();

View File

@@ -1,4 +1,3 @@
/* eslint-disable jest/no-mocks-import */
import path from 'node:path';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';

View File

@@ -28,6 +28,7 @@ const logger: Logger = {
warn: vi.fn(),
http: vi.fn(),
trace: vi.fn(),
fatal: vi.fn(),
};
vi.setConfig({ testTimeout: 20000 });

View File

@@ -1,4 +1,3 @@
/* eslint-disable jest/no-mocks-import */
import fs from 'node:fs';
import path from 'node:path';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
@@ -16,6 +15,7 @@ const logger: Logger = {
warn: vi.fn(),
http: vi.fn(),
trace: vi.fn(),
fatal: vi.fn(),
};
describe('Local Database', () => {

View File

@@ -16,6 +16,7 @@ const logger: Logger = {
warn: vi.fn(),
http: vi.fn(),
trace: vi.fn(),
fatal: vi.fn(),
};
describe('Utitlies', () => {

View File

@@ -72,7 +72,7 @@ describe('MemoryHandler', () => {
expect(updated.name).toBe(pkgExample.name);
});
test('should fail on update a package', async () => {
test('should fail on update a package - mock implementation', async () => {
mockParsePackage.mockImplementationOnce(() => {
throw new Error('error on parse');
});
@@ -86,7 +86,7 @@ describe('MemoryHandler', () => {
);
});
test('should fail updateHandler update a package', async () => {
test('should fail on update a package - internal error', async () => {
const localMemory = new LocalMemory(memoryConfig, defaultConfig);
const pkgName = 'test6';
const handler = localMemory.getPackageStorage(pkgName);
@@ -99,7 +99,7 @@ describe('MemoryHandler', () => {
).rejects.toEqual(errorUtils.getInternalError('some error'));
});
test('should fail on update a package', async () => {
test('should fail on update a package - throw error', async () => {
const localMemory = new LocalMemory(memoryConfig, defaultConfig);
const pkgName = 'test7';
const handler = localMemory.getPackageStorage(pkgName);

View File

@@ -60,7 +60,7 @@
"react/jsx-curly-brace-presence": ["warn", { "props": "ignore", "children": "ignore" }],
"react/jsx-pascal-case": ["error"],
"react/jsx-props-no-multi-spaces": ["error"],
"react/jsx-sort-default-props": ["error"],
"react/sort-default-props": ["error"],
"react/jsx-sort-props": ["error"],
"react/no-string-refs": ["error"],
"react/no-danger-with-children": ["error"],
@@ -78,7 +78,6 @@
"react-hooks/exhaustive-deps": "warn",
"verdaccio/jsx-no-style": ["warn"],
"verdaccio/jsx-spread": ["warn"],
"jest/expect-expect": 0,
"quote-props":["error", "as-needed"],
"prefer-spread": 1,
"linebreak-style": 0,
@@ -94,7 +93,6 @@
"__DEBUG__": true
},
"env": {
"browser": true,
"jest/globals": true
"browser": true
}
}

View File

@@ -1996,7 +1996,7 @@ describe('storage', () => {
).rejects.toThrow(errorUtils.getServiceUnavailable(API_ERROR.SERVER_TIME_OUT));
});
test('should fetch abbreviated version of manifest ', async () => {
test('should fetch abbreviated version of manifest', async () => {
const fooManifest = generateLocalPackageMetadata('foo', '1.0.0');
nock(domain).get('/foo').reply(201, fooManifest);
const config = new Config(

View File

@@ -12,18 +12,19 @@
"email": "juanpicado19@gmail.com"
},
"dependencies": {
"@vitest/eslint-plugin": "1.4.2",
"eslint-config-google": "0.14.0",
"eslint-config-prettier": "8.10.0",
"eslint-config-prettier": "10.1.8",
"eslint-plugin-babel": "5.3.1",
"eslint-plugin-cypress": "2.15.2",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jest": "27.9.0",
"eslint-plugin-cypress": "3.6.0",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-prettier": "5.2.1",
"eslint-plugin-react": "7.37.2",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-simple-import-sort": "10.0.0",
"eslint-plugin-verdaccio": "10.0.0"
"eslint-plugin-prettier": "5.5.4",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "7.0.1",
"eslint-plugin-simple-import-sort": "12.1.1",
"eslint-plugin-verdaccio": "10.0.0",
"eslint-plugin-vitest-globals": "1.5.0"
},
"repository": {
"type": "https",

View File

@@ -3,7 +3,7 @@ module.exports = {
'./rules/base.js',
'./rules/prettier.js',
'./rules/react.js',
'./rules/jest.js',
'./rules/vitest.js',
'./rules/cypress.js',
],
env: {

View File

@@ -1,20 +0,0 @@
module.exports = {
extends: ['plugin:jest/recommended'],
plugins: ['jest'],
env: {
jest: true,
},
rules: {
'jest/no-export': 0,
'jest/no-test-callback': 0,
'jest/expect-expect': 0,
'jest/no-try-expect': 0,
'jest/no-done-callback': 'off',
'jest/no-conditional-expect': 'off',
'jest/valid-title': 'off',
// rules to fix
'jest/no-identical-title': ['warn'],
'jest/no-disabled-tests': ['warn'],
'jest/no-commented-out-tests': ['warn'],
},
};

View File

@@ -12,4 +12,9 @@ module.exports = {
rules: {
'react/prop-types': 0,
},
settings: {
react: {
version: 'detect',
},
},
};

View File

@@ -0,0 +1,18 @@
module.exports = {
// TODO: replace with plugin:@vitest/recommended after update to ESLint 9
extends: ['plugin:@vitest/legacy-recommended', 'plugin:vitest-globals/recommended'],
plugins: ['@vitest'],
env: {
'vitest-globals/env': true,
},
rules: {
'@vitest/expect-expect': 'off',
// rules to fix
'@vitest/no-identical-title': ['warn'],
'@vitest/no-disabled-tests': ['warn'],
'@vitest/no-commented-out-tests': ['warn'],
// TODO: Decide whether to use globals or not
// '@vitest/prefer-importing-vitest-globals': ['warn'],
// '@vitest/no-importing-vitest-globals': ['warn'],
},
};

View File

@@ -78,7 +78,6 @@
"react-hooks/exhaustive-deps": "warn",
"verdaccio/jsx-no-style": ["warn"],
"verdaccio/jsx-spread": ["warn"],
"jest/expect-expect": 0,
"quote-props":["error", "as-needed"],
"prefer-spread": 1,
"linebreak-style": 0,
@@ -94,7 +93,6 @@
"__DEBUG__": true
},
"env": {
"browser": true,
"jest/globals": true
"browser": true
}
}

View File

@@ -128,7 +128,7 @@ describe('<ActionBar /> component', () => {
});
});
test('when click button to download ', async () => {
test('when click button to download', async () => {
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={false} />, store);
fireEvent.click(screen.getByTestId('download-tarball-btn'));
await waitFor(() => {

View File

@@ -42,6 +42,7 @@ const Developers: React.FC<Props> = ({ type, visibleMax = VISIBLE_MAX, packageMe
if (!developers.length) {
return;
}
// eslint-disable-next-line
setVisibleDevelopers(developers.slice(0, visibleDevelopersMax));
}, [developers, visibleDevelopersMax]);

2044
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,5 +6,6 @@ export default defineConfig({
coverage: {
exclude: ['./build', 'test'],
},
globals: true,
},
});