Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup NodeJs
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
registry-url: 'https://registry.npmjs.org'

- name: Update npm
run: npm install -g npm@latest

- name: Install dependencies
run: npm ci

Expand Down
15 changes: 5 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,16 @@ jobs:
uses: actions/checkout@v4

- name: Install
run: |
npm ci
run: npm ci

- name: Audit
run: |
npm audit
run: npm audit

- name: Lint
run: |
npm run lint
run: npm run lint

- name: Test
run: |
npm test
run: npm test

- name: Build
run: |
npm run build
run: npm run build
3 changes: 2 additions & 1 deletion tests/classes/Manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { License } from '../../src/types/License';
import { SystemType } from '../../src/types/SystemType';
import { Architecture } from '../../src/types/Architecture';
import { packageCompatibleFiles } from '../../src/helpers/package';
import { omitDownloads } from '../testUtils';

test('Manager add multiple package versions', () => {
const manager = new Manager(RegistryType.Plugins);
Expand Down Expand Up @@ -187,7 +188,7 @@ test('Manager sync from registries', async () => {
const manager = new Manager(RegistryType.Plugins);
await manager.sync();
const pkg = manager.getPackage(PLUGIN_PACKAGE.slug);
expect(pkg?.getVersion(PLUGIN_PACKAGE.version)).toEqual(PLUGIN);
expect(omitDownloads(pkg?.getVersion(PLUGIN_PACKAGE.version))).toEqual(omitDownloads(PLUGIN));
});

test('Manager sync with existing package', async () => {
Expand Down
29 changes: 15 additions & 14 deletions tests/classes/ManagerLocal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { dirDelete, fileReadJson } from '../../src/helpers/file';
import { RegistryType } from '../../src/types/Registry';
import { ConfigInterface } from '../../src/types/Config';
import { PackageVersion } from '../../src/types/Package';
import { omitDownloads } from '../testUtils';

const APP_DIR: string = 'test';
const CONFIG: ConfigInterface = {
Expand Down Expand Up @@ -52,15 +53,15 @@ test('Plugin sync, install, rescan, uninstall', async () => {

const pkgReturned: PackageVersion | void = await manager.install(PLUGIN_PACKAGE.slug, PLUGIN_PACKAGE.version);
const pkgGet = manager.getPackage(PLUGIN_PACKAGE.slug);
expect(pkgReturned).toEqual(PLUGIN_INSTALLED);
expect(pkgGet?.getVersion(PLUGIN_PACKAGE.version)).toEqual(PLUGIN_INSTALLED);
expect(omitDownloads(pkgReturned)).toEqual(omitDownloads(PLUGIN_INSTALLED));
expect(omitDownloads(pkgGet?.getVersion(PLUGIN_PACKAGE.version))).toEqual(omitDownloads(PLUGIN_INSTALLED));

manager.scan();
const pkgGet2 = manager.getPackage(PLUGIN_PACKAGE.slug);
expect(pkgGet2?.getVersion(PLUGIN_PACKAGE.version)).toEqual(PLUGIN_INSTALLED);
expect(omitDownloads(pkgGet2?.getVersion(PLUGIN_PACKAGE.version))).toEqual(omitDownloads(PLUGIN_INSTALLED));

const pkgReturned2: PackageVersion | void = await manager.uninstall(PLUGIN_PACKAGE.slug, PLUGIN_PACKAGE.version);
expect(pkgReturned2).toEqual(PLUGIN);
expect(omitDownloads(pkgReturned2)).toEqual(omitDownloads(PLUGIN));
});

test('Preset sync, install, rescan, uninstall', async () => {
Expand All @@ -86,15 +87,15 @@ test('Project sync, install, rescan, uninstall', async () => {

const pkgReturned: PackageVersion | void = await manager.install(PROJECT_PACKAGE.slug, PROJECT_PACKAGE.version);
const pkgGet = manager.getPackage(PROJECT_PACKAGE.slug);
expect(pkgReturned).toEqual(PROJECT_INSTALLED);
expect(pkgGet?.getVersion(PROJECT_PACKAGE.version)).toEqual(PROJECT_INSTALLED);
expect(omitDownloads(pkgReturned)).toEqual(omitDownloads(PROJECT_INSTALLED));
expect(omitDownloads(pkgGet?.getVersion(PROJECT_PACKAGE.version))).toEqual(omitDownloads(PROJECT_INSTALLED));

manager.scan();
const pkgGet2 = manager.getPackage(PROJECT_PACKAGE.slug);
expect(pkgGet2?.getVersion(PROJECT_PACKAGE.version)).toEqual(PROJECT_INSTALLED);
expect(omitDownloads(pkgGet2?.getVersion(PROJECT_PACKAGE.version))).toEqual(omitDownloads(PROJECT_INSTALLED));

const pkgReturned2: PackageVersion | void = await manager.uninstall(PROJECT_PACKAGE.slug, PROJECT_PACKAGE.version);
expect(pkgReturned2).toEqual(PROJECT);
expect(omitDownloads(pkgReturned2)).toEqual(omitDownloads(PROJECT));
});

test('Project sync, install project, install dependencies, uninstall dependencies', async () => {
Expand All @@ -106,14 +107,14 @@ test('Project sync, install project, install dependencies, uninstall dependencie

await manager.installDependencies(PROJECT_PATH);
await pluginManager.scan();
expect(pluginManager.toJSON()).toEqual({
[PLUGIN_PACKAGE.slug]: PLUGIN_PACKAGE_INSTALLED,
expect(omitDownloads(pluginManager.toJSON())).toEqual({
[PLUGIN_PACKAGE.slug]: omitDownloads(PLUGIN_PACKAGE_INSTALLED),
});
await manager.uninstallDependencies(PROJECT_PATH);
await pluginManager.scan();
// TODO update when headless installation is working.
expect(pluginManager.toJSON()).toEqual({
[PLUGIN_PACKAGE.slug]: PLUGIN_PACKAGE_INSTALLED,
expect(omitDownloads(pluginManager.toJSON())).toEqual({
[PLUGIN_PACKAGE.slug]: omitDownloads(PLUGIN_PACKAGE_INSTALLED),
});
});

Expand All @@ -122,8 +123,8 @@ test('Project sync, install project, add new dependency, remove new dependency',
await manager.sync();
await manager.install(PROJECT_PACKAGE.slug, PROJECT_PACKAGE.version);
const pkgDeps = await manager.installDependency(PLUGIN_PACKAGE.slug, '1.3.4', PROJECT_PATH);
expect(pkgDeps).toEqual(PROJECT_DEPS);
expect(omitDownloads(pkgDeps)).toEqual(omitDownloads(PROJECT_DEPS));

const pkgNoDeps = await manager.uninstallDependency(PLUGIN_PACKAGE.slug, '1.3.4', PROJECT_PATH);
expect(pkgNoDeps).toEqual(PROJECT_NO_DEPS);
expect(omitDownloads(pkgNoDeps)).toEqual(omitDownloads(PROJECT_NO_DEPS));
});
25 changes: 25 additions & 0 deletions tests/testUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Deep-clones `value`, dropping any key in `keys` at any depth. Used to compare fixtures against
// real results while excluding fields that are inherently non-reproducible - see `omitDownloads`.
export function omitKeysDeep<T>(value: T, keys: string[]): T {
if (Array.isArray(value)) return value.map(item => omitKeysDeep(item, keys)) as T;
if (value && typeof value === 'object') {
const result: any = {};
for (const [key, val] of Object.entries(value)) {
if (keys.includes(key)) continue;
result[key] = omitKeysDeep(val, keys);
}
return result;
}
return value;
}

// `downloads` is computed fresh at build time from live GitHub release download counts (see
// registry's enrichDownloads()) - unlike every other field on these fixtures (hash, size, date),
// it changes continuously in the real, live registry these tests sync against, and is only ever
// set when > 0 (omitted otherwise). Because it can be entirely absent, an asymmetric matcher like
// `expect.any(Number)` can't stand in for it - vitest's toEqual still requires the key to exist on
// both sides before consulting a matcher. So exclude it from both the actual result and the
// expected fixture before comparing, rather than asserting a point-in-time snapshot of it.
export function omitDownloads<T>(value: T): T {
return omitKeysDeep(value, ['downloads']);
}
Loading