Skip to content

Commit

Permalink
Allow negative limits
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Sep 12, 2021
1 parent e82f782 commit c958716
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/bin/config/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Default: false`,
describe: `Report when the average duration has increased by more than a
specific percentage such as "50%".
Negative percentages like "-50%" can be used for decreases instead.
The limit can be scoped to specific combinations by appending their identifiers
after the percentage.
- The syntax is the same as the "select" configuration property.
Expand Down
29 changes: 22 additions & 7 deletions src/history/compare/limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ import { parseLimits } from './parse.js'
// during measuring (`run` command). It is not intended to be shown in
// reporting. Instead, `showDiff` should be used for similar reporting-focused
// purposes.
// The `limit` can check either for increase or decrease depending on whether
// its percentage is positive or not. This is because:
// - A decrease percentage is the inverse from an increase percentage
// (e.g. +100% is reverted by -50%), i.e. requires different limits.
// - Users might want different values for increase and decrease.
// - Some units do not have directions, i.e. one cannot know programmatically
// whether an increase or a decrease is more desirable. This means users must
// explicitly specify it.
export const checkLimits = function ({ combinations }, { limit }) {
const combinationsWithDiff = combinations.filter(hasDiff)

Expand Down Expand Up @@ -41,7 +49,9 @@ const checkCombinationLimits = function ({
combination,
combination: {
name,
stats: { diff },
stats: {
diff: { raw: diff },
},
},
limits,
}) {
Expand All @@ -53,24 +63,29 @@ const checkCombinationLimits = function ({
return
}

const { threshold } = limit
const { threshold, higher } = limit

if (diff <= threshold) {
if (isBelowThreshold(diff, threshold, higher)) {
return
}

return getLimitError(name, diff, threshold)
return getLimitError({ name, diff, threshold, higher })
}

const getLimitError = function (name, diff, threshold) {
const isBelowThreshold = function (diff, threshold, higher) {
return higher ? diff <= threshold : diff >= threshold
}

const getLimitError = function ({ name = 'oo', diff, threshold, higher }) {
const nameA = stripAnsi(name)
const thresholdStr = threshold * PERCENTAGE_RATIO
const diffStr = serializeDiff(diff)
return `${nameA} should be at most ${thresholdStr}% slower but is ${diffStr}% slower`
const higherStr = higher ? 'higher' : 'lower'
return `${nameA} should be at most ${thresholdStr}% ${higherStr} but it is ${diffStr}% ${higherStr}.`
}

const serializeDiff = function (diff) {
const percentage = diff * PERCENTAGE_RATIO
const percentage = Math.abs(diff) * PERCENTAGE_RATIO
return percentage
.toPrecision(PERCENTAGE_PRECISION)
.replace(ONLY_ZEROS_REGEXP, '')
Expand Down
12 changes: 7 additions & 5 deletions src/history/compare/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ const parseLimit = function (singleLimit, combinations) {
const [rawPercentage, ...rawGroups] = singleLimit
.trim()
.split(PERCENT_SEPARATOR_REGEXP)
const threshold = parsePercentage(rawPercentage)
const { threshold, higher } = parsePercentage(rawPercentage)
const selectors = parseLimitSelectors(rawGroups, combinations)
return { threshold, selectors }
return { threshold, higher, selectors }
}

const PERCENT_SEPARATOR_REGEXP = /\s+/u
Expand All @@ -34,13 +34,15 @@ const parsePercentage = function (rawPercentage) {

const threshold = Number(percentage)

if (!Number.isInteger(threshold) || threshold < 0) {
if (!Number.isInteger(threshold)) {
throw new UserError(
`The 'limit' configuration property's percentage must be a positive integer: ${rawPercentage}`,
`The 'limit' configuration property's percentage must be an integer: ${rawPercentage}`,
)
}

return threshold / PERCENTAGE_RATIO
const higher = threshold > 0
const thresholdA = Math.abs(threshold) / PERCENTAGE_RATIO
return { threshold: thresholdA, higher }
}

const PERCENTAGE_REGEXP = /%$/u
Expand Down

0 comments on commit c958716

Please sign in to comment.