Skip to content

Commit

Permalink
core(budget): throw error on duplicate budget types (#8915)
Browse files Browse the repository at this point in the history
  • Loading branch information
brendankenny authored May 16, 2019
1 parent 4a74d17 commit 641ab51
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
22 changes: 22 additions & 0 deletions lighthouse-core/config/budget.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ class Budget {
}
}

/**
* Asserts that `strings` has no duplicate strings in it, throwing an error if
* it does. `arrayName` is included for nicer logging.
* @param {Array<string>} strings
* @param {string} arrayName
*/
static assertNoDuplicateStrings(strings, arrayName) {
const foundStrings = new Set();
for (const string of strings) {
if (foundStrings.has(string)) {
throw new Error(`${arrayName} has duplicate entry of type '${string}'`);
}
foundStrings.add(string);
}
}

/**
* @param {Record<string, unknown>} resourceBudget
* @return {LH.Budget.ResourceBudget}
Expand Down Expand Up @@ -136,18 +152,24 @@ class Budget {

if (isArrayOfUnknownObjects(resourceSizes)) {
budget.resourceSizes = resourceSizes.map(Budget.validateResourceBudget);
Budget.assertNoDuplicateStrings(budget.resourceSizes.map(r => r.resourceType),
`budgets[${index}].resourceSizes`);
} else if (resourceSizes !== undefined) {
throw new Error(`Invalid resourceSizes entry in budget at index ${index}`);
}

if (isArrayOfUnknownObjects(resourceCounts)) {
budget.resourceCounts = resourceCounts.map(Budget.validateResourceBudget);
Budget.assertNoDuplicateStrings(budget.resourceCounts.map(r => r.resourceType),
`budgets[${index}].resourceCounts`);
} else if (resourceCounts !== undefined) {
throw new Error(`Invalid resourceCounts entry in budget at index ${index}`);
}

if (isArrayOfUnknownObjects(timings)) {
budget.timings = timings.map(Budget.validateTimingBudget);
Budget.assertNoDuplicateStrings(budget.timings.map(r => r.metric),
`budgets[${index}].timings`);
} else if (timings !== undefined) {
throw new Error(`Invalid timings entry in budget at index ${index}`);
}
Expand Down
18 changes: 18 additions & 0 deletions lighthouse-core/test/config/budget-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ describe('Budget', () => {
assert.throws(_ => Budget.initializeBudget(budget),
/Resource Budget has unrecognized properties: \[browser\]/);
});

it('throws when a duplicate resourceType is specified in resourceSizes', () => {
budget[1].resourceSizes.push({resourceType: 'script', budget: 100});
assert.throws(_ => Budget.initializeBudget(budget),
/budgets\[1\]\.resourceSizes has duplicate entry of type 'script'/);
});

it('throws when a duplicate resourceType is specified in resourceCounts', () => {
budget[0].resourceCounts.push({resourceType: 'third-party', budget: 100});
assert.throws(_ => Budget.initializeBudget(budget),
/budgets\[0\]\.resourceCounts has duplicate entry of type 'third-party'/);
});
});

describe('timing budget validation', () => {
Expand All @@ -172,5 +184,11 @@ describe('Budget', () => {
assert.throws(_ => Budget.initializeBudget(budget),
/Timing Budget has unrecognized properties: \[device, location\]/);
});

it('throws when a duplicate metric type is specified in timings', () => {
budget[0].timings.push({metric: 'interactive', budget: 1000});
assert.throws(_ => Budget.initializeBudget(budget),
/budgets\[0\]\.timings has duplicate entry of type 'interactive'/);
});
});
});

0 comments on commit 641ab51

Please sign in to comment.