Skip to content

Commit 675a828

Browse files
authored
core(plugins): allow supportedModes in category (#13921)
1 parent 3b8b90b commit 675a828

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

lighthouse-core/config/config-plugin.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,24 @@ function isObjectOfUnknownProperties(val) {
2323
return typeof val === 'object' && val !== null && !Array.isArray(val);
2424
}
2525

26+
/**
27+
* @param {unknown} str
28+
* @return {str is LH.Gatherer.GatherMode}
29+
*/
30+
function objectIsGatherMode(str) {
31+
if (typeof str !== 'string') return false;
32+
return str === 'navigation' || str === 'timespan' || str === 'snapshot';
33+
}
34+
35+
/**
36+
* @param {unknown} arr
37+
* @return {arr is Array<LH.Gatherer.GatherMode>}
38+
*/
39+
function isArrayOfGatherModes(arr) {
40+
if (!Array.isArray(arr)) return false;
41+
return arr.every(objectIsGatherMode);
42+
}
43+
2644
/**
2745
* Asserts that obj has no own properties, throwing a nice error message if it does.
2846
* Plugin and object name are included for nicer logging.
@@ -124,6 +142,7 @@ class ConfigPlugin {
124142
description,
125143
manualDescription,
126144
auditRefs: auditRefsJson,
145+
supportedModes,
127146
...invalidRest
128147
} = categoryJson;
129148

@@ -138,13 +157,20 @@ class ConfigPlugin {
138157
if (!i18n.isStringOrIcuMessage(manualDescription) && manualDescription !== undefined) {
139158
throw new Error(`${pluginName} has an invalid category manualDescription.`);
140159
}
160+
if (!isArrayOfGatherModes(supportedModes) && supportedModes !== undefined) {
161+
throw new Error(
162+
`${pluginName} supportedModes must be an array, ` +
163+
`valid array values are "navigation", "timespan", and "snapshot".`
164+
);
165+
}
141166
const auditRefs = ConfigPlugin._parseAuditRefsList(auditRefsJson, pluginName);
142167

143168
return {
144169
title,
145170
auditRefs,
146171
description: description,
147172
manualDescription: manualDescription,
173+
supportedModes,
148174
};
149175
}
150176

lighthouse-core/test/config/__snapshots__/config-plugin-test.js.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Object {
2323
],
2424
"description": "A nice plugin for nice testing",
2525
"manualDescription": undefined,
26+
"supportedModes": Array [
27+
"navigation",
28+
],
2629
"title": "Nice Plugin",
2730
},
2831
},

lighthouse-core/test/config/config-plugin-test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const nicePlugin = {
3939
{id: 'nice-audit', weight: 1, group: 'group-a'},
4040
{id: 'installable-manifest', weight: 220},
4141
],
42+
supportedModes: ['navigation'],
4243
},
4344
};
4445

@@ -115,6 +116,7 @@ describe('ConfigPlugin', () => {
115116
auditRefs: [
116117
{id: 'evil-audit', weight: 0, group: undefined},
117118
],
119+
supportedModes: ['navigation'],
118120
};
119121

120122
const evilPlugin = {
@@ -242,13 +244,34 @@ describe('ConfigPlugin', () => {
242244
assert.ok(pluginJson);
243245
});
244246

247+
it('accepts a category with no supportedModes', () => {
248+
const pluginClone = deepClone(nicePlugin);
249+
delete pluginClone.category.supportedModes;
250+
const pluginJson = ConfigPlugin.parsePlugin(pluginClone, nicePluginName);
251+
assert.ok(pluginJson);
252+
});
253+
245254
it('throws if category has an invalid manualDescription', () => {
246255
const pluginClone = deepClone(nicePlugin);
247256
pluginClone.category.manualDescription = 55;
248257
assert.throws(() => ConfigPlugin.parsePlugin(pluginClone, nicePluginName),
249258
/^Error: lighthouse-plugin-nice-plugin has an invalid category manualDescription/);
250259
});
251260

261+
it('throws if supported modes is not an array', () => {
262+
const pluginClone = deepClone(nicePlugin);
263+
pluginClone.category.supportedModes = 55;
264+
assert.throws(() => ConfigPlugin.parsePlugin(pluginClone, nicePluginName),
265+
/^Error: lighthouse-plugin-nice-plugin supportedModes must be an array/);
266+
});
267+
268+
it('throws if supported modes is not an array of valid gather modes', () => {
269+
const pluginClone = deepClone(nicePlugin);
270+
pluginClone.category.supportedModes = ['invalid-mode'];
271+
assert.throws(() => ConfigPlugin.parsePlugin(pluginClone, nicePluginName),
272+
/^Error: lighthouse-plugin-nice-plugin supportedModes must be an array/);
273+
});
274+
252275
describe('`category.auditRefs`', () => {
253276
it('correctly passes through the contained auditRefs', () => {
254277
const pluginJson = ConfigPlugin.parsePlugin(nicePlugin, nicePluginName);

0 commit comments

Comments
 (0)