-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(cli): merge skip and only plugin filters
- Loading branch information
1 parent
f6f82ed
commit df5c5ac
Showing
7 changed files
with
255 additions
and
291 deletions.
There are no files selected for viewing
59 changes: 59 additions & 0 deletions
59
packages/cli/src/lib/implementation/filter-plugins.middleware.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { filterItemRefsBy } from '@code-pushup/utils'; | ||
import type { OnlyPluginsOptions } from './only-plugins.model'; | ||
import type { SkipPluginsOptions } from './skip-plugins.model'; | ||
import { validatePluginFilterOption } from './validate-plugin-filter-options.utils'; | ||
|
||
export function filterPluginsMiddleware< | ||
T extends SkipPluginsOptions & OnlyPluginsOptions, | ||
>(originalProcessArgs: T): T { | ||
const { | ||
plugins, | ||
categories = [], | ||
skipPlugins = [], | ||
onlyPlugins = [], | ||
verbose, | ||
} = originalProcessArgs; | ||
|
||
if (skipPlugins.length === 0 && onlyPlugins.length === 0) { | ||
return { ...originalProcessArgs, categories }; | ||
} | ||
|
||
validatePluginFilterOption( | ||
'skipPlugins', | ||
{ plugins, categories }, | ||
{ pluginsToFilter: skipPlugins, verbose }, | ||
); | ||
validatePluginFilterOption( | ||
'onlyPlugins', | ||
{ plugins, categories }, | ||
{ pluginsToFilter: onlyPlugins, verbose }, | ||
); | ||
|
||
const validSkipPlugins = new Set( | ||
skipPlugins.filter(sP => plugins.some(p => p.slug === sP)), | ||
); | ||
const pluginsAfterSkip = plugins.filter( | ||
({ slug }) => !validSkipPlugins.has(slug), | ||
); | ||
|
||
const validOnlyPlugins = new Set( | ||
onlyPlugins.filter(oP => pluginsAfterSkip.some(p => p.slug === oP)), | ||
); | ||
const filteredPlugins = | ||
validOnlyPlugins.size > 0 | ||
? pluginsAfterSkip.filter(({ slug }) => validOnlyPlugins.has(slug)) | ||
: pluginsAfterSkip; | ||
|
||
const filteredCategories = | ||
filteredPlugins.length > 0 | ||
? filterItemRefsBy(categories, ({ plugin }) => | ||
filteredPlugins.some(({ slug }) => slug === plugin), | ||
) | ||
: categories; | ||
|
||
return { | ||
...originalProcessArgs, | ||
plugins: filteredPlugins, | ||
categories: filteredCategories, | ||
}; | ||
} |
193 changes: 193 additions & 0 deletions
193
packages/cli/src/lib/implementation/filter-plugins.middleware.unit.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
import { describe, expect, vi } from 'vitest'; | ||
import type { CategoryConfig, PluginConfig } from '@code-pushup/models'; | ||
import { ui } from '@code-pushup/utils'; | ||
import { filterPluginsMiddleware } from './filter-plugins.middleware'; | ||
|
||
vi.mock('@code-pushup/core', async () => { | ||
const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = | ||
await vi.importActual('@code-pushup/test-utils'); | ||
const core: object = await vi.importActual('@code-pushup/core'); | ||
return { | ||
...core, | ||
readRcByPath: vi.fn().mockResolvedValue(CORE_CONFIG_MOCK), | ||
autoloadRc: vi.fn().mockResolvedValue(CORE_CONFIG_MOCK), | ||
}; | ||
}); | ||
|
||
describe('filterPluginsMiddleware', () => { | ||
it('should fill undefined categories with empty array', () => { | ||
expect( | ||
filterPluginsMiddleware({ | ||
plugins: [{ slug: 'p1' } as PluginConfig], | ||
}), | ||
).toStrictEqual({ | ||
plugins: [{ slug: 'p1' }], | ||
categories: [], | ||
}); | ||
}); | ||
|
||
it('should forward equal values when neither skipPlugins nor onlyPlugins is set', () => { | ||
expect( | ||
filterPluginsMiddleware({ | ||
plugins: [{ slug: 'p1' } as PluginConfig], | ||
categories: [ | ||
{ slug: 'c1', refs: [{ plugin: 'p1' }] } as CategoryConfig, | ||
], | ||
}), | ||
).toStrictEqual({ | ||
plugins: [{ slug: 'p1' }], | ||
categories: [{ slug: 'c1', refs: [{ plugin: 'p1' }] }], | ||
}); | ||
}); | ||
|
||
it('should return original values when neither skipPlugins nor onlyPlugins is provided', () => { | ||
const originalPlugins = [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[]; | ||
const originalCategories = [ | ||
{ | ||
slug: 'c1', | ||
refs: [{ plugin: 'p1', slug: 'a1-p1' }], | ||
}, | ||
] as CategoryConfig[]; | ||
|
||
const { plugins, categories } = filterPluginsMiddleware({ | ||
plugins: originalPlugins, | ||
categories: originalCategories, | ||
}); | ||
|
||
expect(plugins).toStrictEqual(originalPlugins); | ||
expect(categories).toStrictEqual(originalCategories); | ||
}); | ||
|
||
it('should return original values when skipPlugins and onlyPlugins are empty', () => { | ||
const originalPlugins = [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[]; | ||
const originalCategories = [ | ||
{ | ||
slug: 'c1', | ||
refs: [{ plugin: 'p1', slug: 'a1-p1' }], | ||
}, | ||
] as CategoryConfig[]; | ||
|
||
const { plugins, categories } = filterPluginsMiddleware({ | ||
plugins: originalPlugins, | ||
categories: originalCategories, | ||
skipPlugins: [], | ||
onlyPlugins: [], | ||
}); | ||
|
||
expect(plugins).toStrictEqual(originalPlugins); | ||
expect(categories).toStrictEqual(originalCategories); | ||
}); | ||
|
||
it('should filter plugins for slug "p1" in onlyPlugins', () => { | ||
const { plugins } = filterPluginsMiddleware({ | ||
onlyPlugins: ['p1'], | ||
plugins: [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[], | ||
categories: [], | ||
}); | ||
expect(plugins).toStrictEqual([expect.objectContaining({ slug: 'p1' })]); | ||
}); | ||
|
||
it('should filter plugins for slug "p2" in skipPlugins', () => { | ||
const { plugins, categories } = filterPluginsMiddleware({ | ||
skipPlugins: ['p2'], | ||
plugins: [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[], | ||
categories: [ | ||
{ | ||
slug: 'c1', | ||
refs: [ | ||
{ plugin: 'p1', slug: 'a1-p1' }, | ||
{ plugin: 'p2', slug: 'a2-p1' }, | ||
], | ||
}, | ||
{ slug: 'c2', refs: [{ plugin: 'p2', slug: 'a1-p2' }] }, | ||
] as CategoryConfig[], | ||
}); | ||
|
||
expect(plugins).toStrictEqual([expect.objectContaining({ slug: 'p1' })]); | ||
expect(categories).toStrictEqual([ | ||
expect.objectContaining({ | ||
slug: 'c1', | ||
refs: [{ plugin: 'p1', slug: 'a1-p1' }], | ||
}), | ||
]); | ||
}); | ||
|
||
it('should forward plugins and categories for a slug not present in plugins', () => { | ||
const originalCategories = [ | ||
{ | ||
slug: 'c1', | ||
refs: [ | ||
{ plugin: 'p1', slug: 'a1-p1' }, | ||
{ plugin: 'p2', slug: 'a2-p1' }, | ||
], | ||
}, | ||
{ slug: 'c2', refs: [{ plugin: 'p2', slug: 'a1-p2' }] }, | ||
] as CategoryConfig[]; | ||
const originalPlugins = [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[]; | ||
const { categories, plugins } = filterPluginsMiddleware({ | ||
onlyPlugins: ['wrong-slug'], | ||
plugins: originalPlugins, | ||
categories: originalCategories, | ||
}); | ||
expect(categories).toStrictEqual(originalCategories); | ||
expect(plugins).toStrictEqual(originalPlugins); | ||
}); | ||
|
||
it('should filter categories for slug "p1" in onlyPlugins', () => { | ||
const { categories } = filterPluginsMiddleware({ | ||
onlyPlugins: ['p1'], | ||
plugins: [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[], | ||
categories: [ | ||
{ | ||
slug: 'c1', | ||
refs: [ | ||
{ plugin: 'p1', slug: 'a1-p1' }, | ||
{ plugin: 'p2', slug: 'a2-p1' }, | ||
], | ||
}, | ||
{ slug: 'c2', refs: [{ plugin: 'p2', slug: 'a1-p2' }] }, | ||
] as CategoryConfig[], | ||
}); | ||
expect(categories).toStrictEqual([ | ||
expect.objectContaining({ | ||
slug: 'c1', | ||
refs: [{ plugin: 'p1', slug: 'a1-p1' }], | ||
}), | ||
]); | ||
}); | ||
|
||
it('should filter plugins when both skipPlugins and onlyPlugins are provided', () => { | ||
const { plugins } = filterPluginsMiddleware({ | ||
onlyPlugins: ['p1'], | ||
skipPlugins: ['p2'], | ||
plugins: [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[], | ||
categories: [], | ||
}); | ||
expect(plugins).toStrictEqual([expect.objectContaining({ slug: 'p1' })]); | ||
}); | ||
|
||
it('should trigger verbose logging when skipPlugins or onlyPlugins removes categories', () => { | ||
const loggerSpy = vi.spyOn(ui().logger, 'info'); | ||
|
||
filterPluginsMiddleware({ | ||
onlyPlugins: ['p1'], | ||
skipPlugins: ['p2'], | ||
plugins: [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[], | ||
categories: [ | ||
{ | ||
slug: 'c1', | ||
refs: [ | ||
{ plugin: 'p1', slug: 'a1-p1' }, | ||
{ plugin: 'p2', slug: 'a2-p1' }, | ||
], | ||
}, | ||
{ slug: 'c2', refs: [{ plugin: 'p2', slug: 'a1-p2' }] }, | ||
] as CategoryConfig[], | ||
verbose: true, | ||
}); | ||
|
||
expect(loggerSpy).toHaveBeenCalledWith( | ||
expect.stringContaining('removed the following categories'), | ||
); | ||
}); | ||
}); |
45 changes: 0 additions & 45 deletions
45
packages/cli/src/lib/implementation/only-plugins.middleware.ts
This file was deleted.
Oops, something went wrong.
94 changes: 0 additions & 94 deletions
94
packages/cli/src/lib/implementation/only-plugins.middleware.unit.test.ts
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.