Skip to content

Commit 1fb77ae

Browse files
paulirishbrendankenny
authored andcommitted
filterPasses -> validatePasses (#608)
* filterPasses -> validatePasses. Don't mutate the config * cleanup config constructor. * remove audit whitelist.
1 parent 5c72d72 commit 1fb77ae

File tree

6 files changed

+56
-157
lines changed

6 files changed

+56
-157
lines changed

lighthouse-cli/index.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ const cli = yargs
5050
'load-page',
5151
'save-assets',
5252
'save-artifacts',
53-
'audit-whitelist',
5453
'list-all-audits',
5554
'list-trace-categories',
5655
'config-path'
@@ -60,7 +59,6 @@ const cli = yargs
6059
'load-page': 'Loads the page',
6160
'save-assets': 'Save the trace contents & screenshots to disk',
6261
'save-artifacts': 'Save all gathered artifacts to disk',
63-
'audit-whitelist': 'Comma separated list of audits to run',
6462
'list-all-audits': 'Prints a list of all available audits and exits',
6563
'list-trace-categories': 'Prints a list of all required trace categories and exits',
6664
'config-path': 'The absolute path to the config JSON.'
@@ -92,7 +90,6 @@ Example: --output-path=./lighthouse-results.html`
9290
// default values
9391
.default('mobile', true)
9492
.default('load-page', true)
95-
.default('audit-whitelist', 'all')
9693
.default('output', Printer.OUTPUT_MODE.pretty)
9794
.default('output-path', 'stdout')
9895
.check(argv => {
@@ -138,13 +135,6 @@ if (cli.verbose) {
138135
flags.logLevel = 'error';
139136
}
140137

141-
// Normalize audit whitelist.
142-
if (!flags.auditWhitelist || flags.auditWhitelist === 'all') {
143-
flags.auditWhitelist = null;
144-
} else {
145-
flags.auditWhitelist = new Set(flags.auditWhitelist.split(',').map(a => a.toLowerCase()));
146-
}
147-
148138
// kick off a lighthouse run
149139
lighthouse(url, flags, config)
150140
.then(results => Printer.write(results, outputMode, outputPath))

lighthouse-core/config/config.js

Lines changed: 30 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -106,29 +106,22 @@ function cleanTrace(trace) {
106106
return trace;
107107
}
108108

109-
function filterPasses(passes, audits, rootPath) {
109+
function validatePasses(passes, audits, rootPath) {
110+
if (!Array.isArray(passes)) {
111+
return;
112+
}
110113
const requiredGatherers = getGatherersNeededByAudits(audits);
111114

112-
// Make sure we only have the gatherers that are needed by the audits
113-
// that have been listed in the config.
114-
const filteredPasses = passes.map(pass => {
115-
const freshPass = Object.assign({}, pass);
116-
117-
freshPass.gatherers = freshPass.gatherers.filter(gatherer => {
115+
// Log if we are running gathers that are not needed by the audits listed in the config
116+
passes.forEach(pass => {
117+
pass.gatherers.forEach(gatherer => {
118118
const GathererClass = GatherRunner.getGathererClass(gatherer, rootPath);
119119
const isGatherRequiredByAudits = requiredGatherers.has(GathererClass.name);
120120
if (isGatherRequiredByAudits === false) {
121-
log.warn('config', `Skipping ${GathererClass.name} gatherer as no audit requires it.`);
121+
log.warn('config', `${GathererClass.name} is included, however no audit requires it.`);
122122
}
123-
return isGatherRequiredByAudits;
124123
});
125-
126-
return freshPass;
127-
})
128-
129-
// Now remove any passes which no longer have gatherers.
130-
.filter(p => p.gatherers.length > 0);
131-
return filteredPasses;
124+
});
132125
}
133126

134127
function getGatherersNeededByAudits(audits) {
@@ -144,33 +137,10 @@ function getGatherersNeededByAudits(audits) {
144137
}, new Set());
145138
}
146139

147-
function filterAudits(audits, auditWhitelist) {
148-
// If there is no whitelist, assume all.
149-
if (!auditWhitelist) {
150-
return Array.from(audits);
151-
}
152-
153-
const rejected = [];
154-
const filteredAudits = audits.filter(a => {
155-
const auditName = a.toLowerCase();
156-
const inWhitelist = auditWhitelist.has(auditName);
157-
158-
if (!inWhitelist) {
159-
rejected.push(auditName);
160-
}
161-
162-
return inWhitelist;
163-
});
164-
165-
if (rejected.length) {
166-
log.log('info', 'Running these audits:', `${filteredAudits.join(', ')}`);
167-
log.log('info', 'Skipping these audits:', `${rejected.join(', ')}`);
140+
function requireAudits(audits, rootPath) {
141+
if (!audits) {
142+
return null;
168143
}
169-
170-
return filteredAudits;
171-
}
172-
173-
function expandAudits(audits, rootPath) {
174144
const Runner = require('../runner');
175145

176146
return audits.map(audit => {
@@ -247,8 +217,9 @@ function assertValidAudit(audit, auditDefinition) {
247217
}
248218

249219
function expandArtifacts(artifacts) {
250-
const expandedArtifacts = Object.assign({}, artifacts);
251-
220+
if (!artifacts) {
221+
return null;
222+
}
252223
// currently only trace logs and performance logs should be imported
253224
if (artifacts.traces) {
254225
Object.keys(artifacts.traces).forEach(key => {
@@ -264,15 +235,14 @@ function expandArtifacts(artifacts) {
264235
}
265236
trace = cleanTrace(trace);
266237

267-
expandedArtifacts.traces[key] = trace;
238+
artifacts.traces[key] = trace;
268239
});
269240
}
270-
271241
if (artifacts.performanceLog) {
272-
expandedArtifacts.networkRecords = recordsFromLogs(require(artifacts.performanceLog));
242+
artifacts.networkRecords = recordsFromLogs(require(artifacts.performanceLog));
273243
}
274244

275-
return expandedArtifacts;
245+
return artifacts;
276246
}
277247

278248
/**
@@ -283,27 +253,24 @@ class Config {
283253
* @constructor
284254
* @param{Object} config
285255
*/
286-
constructor(configJSON, auditWhitelist, configPath) {
256+
constructor(configJSON, configPath) {
287257
if (!configJSON) {
288258
configJSON = defaultConfig;
289259
}
290-
260+
// We don't want to mutate the original config object
261+
configJSON = JSON.parse(JSON.stringify(configJSON));
291262
// Store the directory of the config path, if one was provided.
292263
this._configDir = configPath ? path.dirname(configPath) : undefined;
293264

294-
this._audits = configJSON.audits ? expandAudits(
295-
filterAudits(configJSON.audits, auditWhitelist), this._configDir
296-
) : null;
297-
// filterPasses expects audits to have been expanded
298-
this._passes = configJSON.passes ?
299-
filterPasses(configJSON.passes, this._audits, this._configDir) :
300-
null;
301-
this._auditResults = configJSON.auditResults ? Array.from(configJSON.auditResults) : null;
302-
this._artifacts = null;
303-
if (configJSON.artifacts) {
304-
this._artifacts = expandArtifacts(configJSON.artifacts);
305-
}
306-
this._aggregations = configJSON.aggregations ? Array.from(configJSON.aggregations) : null;
265+
this._passes = configJSON.passes || null;
266+
this._auditResults = configJSON.auditResults || null;
267+
this._aggregations = configJSON.aggregations || null;
268+
269+
this._audits = requireAudits(configJSON.audits, this._configDir);
270+
this._artifacts = expandArtifacts(configJSON.artifacts);
271+
272+
// validatePasses must follow after audits are required
273+
validatePasses(configJSON.passes, this._audits, this._configDir);
307274
}
308275

309276
/** @type {string} */

lighthouse-core/config/perf.example-custom.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@
33
"network": true,
44
"trace": true,
55
"loadPage": true,
6-
"gatherers": [
7-
"url",
8-
"critical-request-chains",
9-
"screenshots",
10-
"speedline"
11-
]
6+
"gatherers": []
127
}],
138

149
"audits": [

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

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,6 @@ describe('Config', () => {
5151
/Unable to locate/);
5252
});
5353

54-
it('filters gatherers from passes when no audits require them', () => {
55-
const config = new Config({
56-
passes: [{
57-
gatherers: [
58-
'url',
59-
'html',
60-
'viewport'
61-
]
62-
}],
63-
64-
audits: ['viewport']
65-
});
66-
67-
assert.equal(config.passes[0].gatherers.length, 1);
68-
});
69-
7054
it('doesn\'t mutate old gatherers when filtering passes', () => {
7155
const configJSON = {
7256
passes: [{
@@ -99,22 +83,13 @@ describe('Config', () => {
9983
}];
10084

10185
const config = new Config(configJSON);
102-
assert.notEqual(config, configJSON);
103-
assert.ok(config.aggregations);
104-
assert.ok(config.auditResults);
105-
assert.deepStrictEqual(config.aggregations, configJSON.aggregations);
106-
assert.notEqual(config.aggregations, configJSON.aggregations);
107-
assert.notEqual(config.auditResults, configJSON.auditResults);
108-
assert.deepStrictEqual(config.auditResults, configJSON.auditResults);
109-
});
110-
111-
it('returns filtered audits when a whitelist is given', () => {
112-
const config = new Config({
113-
audits: ['is-on-https']
114-
}, new Set(['b']));
115-
116-
assert.ok(Array.isArray(config.audits));
117-
return assert.equal(config.audits.length, 0);
86+
assert.notEqual(config, configJSON, 'Objects are strictly different');
87+
assert.ok(config.aggregations, 'Aggregations array exists');
88+
assert.ok(config.auditResults, 'Audits array exists');
89+
assert.deepStrictEqual(config.aggregations, configJSON.aggregations, 'Aggregations match');
90+
assert.notEqual(config.aggregations, configJSON.aggregations, 'Aggregations not same object');
91+
assert.notEqual(config.auditResults, configJSON.auditResults, 'Audits not same object');
92+
assert.deepStrictEqual(config.auditResults, configJSON.auditResults, 'Audits match');
11893
});
11994

12095
it('expands audits', () => {
@@ -136,7 +111,7 @@ describe('Config', () => {
136111
it('loads an audit relative to a config', () => {
137112
return assert.doesNotThrow(_ => new Config({
138113
audits: ['../fixtures/valid-custom-audit']
139-
}, null, __filename));
114+
}, __filename));
140115
});
141116

142117
it('throws when it finds invalid audits', () => {

0 commit comments

Comments
 (0)