Display one decimal for metrics smaller than 10 (#3735)

* Display one decimal for metrics smaller than 10

* Update test validators

* Run Prettier

* Update GitHub regexes
This commit is contained in:
Pierre-Yves B
2019-07-17 20:00:29 +01:00
committed by GitHub
parent e556ac2793
commit 3dbe655611
10 changed files with 70 additions and 32 deletions

View File

@@ -97,28 +97,36 @@ t.create('Topics')
.get('/https/meta.discourse.org/topics.json')
.expectBadge({
label: 'discourse',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? topics$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) topics$/
),
})
t.create('Posts')
.get('/https/meta.discourse.org/posts.json')
.expectBadge({
label: 'discourse',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? posts$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) posts$/
),
})
t.create('Users')
.get('/https/meta.discourse.org/users.json')
.expectBadge({
label: 'discourse',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? users$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) users$/
),
})
t.create('Likes')
.get('/https/meta.discourse.org/likes.json')
.expectBadge({
label: 'discourse',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? likes$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) likes$/
),
})
t.create('Status')

View File

@@ -1,13 +1,14 @@
'use strict'
const Joi = require('@hapi/joi')
const { isMetric } = require('../test-validators')
const t = (module.exports = require('../tester').createServiceTester())
t.create('Commits since')
.get('/badges/shields/a0663d8da53fb712472c02665e6ff7547ba945b7.json')
.expectBadge({
label: Joi.string().regex(/^(commits since){1}[\s\S]+$/),
message: Joi.string().regex(/^\w+$/),
message: isMetric,
color: 'blue',
})
@@ -15,21 +16,21 @@ t.create('Commits since (branch)')
.get('/badges/shields/60be4859585650e8c2b87669e3a39d98ca084e98/gh-pages.json')
.expectBadge({
label: Joi.string().regex(/^(commits since){1}[\s\S]+$/),
message: Joi.string().regex(/^\w+$/),
message: isMetric,
})
t.create('Commits since by latest release')
.get('/microsoft/typescript/latest.json')
.expectBadge({
label: Joi.string().regex(/^(commits since){1}[\s\S]+$/),
message: Joi.string().regex(/^\d+\w?$/),
message: isMetric,
})
t.create('Commits since by latest release (branch)')
.get('/microsoft/typescript/latest/master.json')
.expectBadge({
label: Joi.string().regex(/^(commits since){1}[\s\S]+$/),
message: Joi.string().regex(/^\d+\w?$/),
message: isMetric,
})
t.create('Commits since (version not found)')

View File

@@ -40,21 +40,27 @@ t.create('downloads for specific asset without slash')
.get('/downloads/atom/atom/v0.190.0/atom-amd64.deb.json')
.expectBadge({
label: 'downloads@v0.190.0',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? \[atom-amd64\.deb\]$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) \[atom-amd64\.deb\]$/
),
})
t.create('downloads for specific asset from latest release')
.get('/downloads/atom/atom/latest/atom-amd64.deb.json')
.expectBadge({
label: 'downloads@latest',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? \[atom-amd64\.deb\]$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) \[atom-amd64\.deb\]$/
),
})
t.create('downloads-pre for specific asset from latest release')
.get('/downloads-pre/atom/atom/latest/atom-amd64.deb.json')
.expectBadge({
label: 'downloads@latest',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? \[atom-amd64\.deb\]$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) \[atom-amd64\.deb\]$/
),
})
t.create('downloads for release with slash')
@@ -66,7 +72,7 @@ t.create('downloads for specific asset with slash')
.expectBadge({
label: 'downloads@stable/v2.2.8',
message: Joi.string().regex(
/^[0-9]+[kMGTPEZY]? \[dban-2\.2\.8_i586\.iso\]$/
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) \[dban-2\.2\.8_i586\.iso\]$/
),
})

View File

@@ -1,13 +1,13 @@
'use strict'
const Joi = require('@hapi/joi')
const { isMetric } = require('../test-validators')
const t = (module.exports = require('../tester').createServiceTester())
t.create('Followers')
.get('/webcaetano.json')
.expectBadge({
label: 'followers',
message: Joi.string().regex(/^\w+$/),
message: isMetric,
})
t.create('Followers (user not found)')

View File

@@ -8,14 +8,16 @@ t.create('GitHub closed pull requests')
.get('/issues-pr-closed/badges/shields.json')
.expectBadge({
label: 'pull requests',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? closed$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) closed$/
),
})
t.create('GitHub closed pull requests raw')
.get('/issues-pr-closed-raw/badges/shields.json')
.expectBadge({
label: 'closed pull requests',
message: Joi.string().regex(/^\w+?$/),
message: isMetric,
})
t.create('GitHub pull requests')
@@ -36,14 +38,16 @@ t.create('GitHub closed issues')
.get('/issues-closed/badges/shields.json')
.expectBadge({
label: 'issues',
message: Joi.string().regex(/^[0-9]+[kMGTPEZY]? closed$/),
message: Joi.string().regex(
/^([0-9]+[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) closed$/
),
})
t.create('GitHub closed issues raw')
.get('/issues-closed-raw/badges/shields.json')
.expectBadge({
label: 'closed issues',
message: Joi.string().regex(/^\w+\+?$/),
message: isMetric,
})
t.create('GitHub open issues')

View File

@@ -1,13 +1,13 @@
'use strict'
const Joi = require('@hapi/joi')
const { isMetric } = require('../test-validators')
const t = (module.exports = require('../tester').createServiceTester())
t.create('Stars')
.get('/badges/shields.json')
.expectBadge({
label: 'stars',
message: Joi.string().regex(/^\w+$/),
message: isMetric,
link: [
'https://github.com/badges/shields',
'https://github.com/badges/shields/stargazers',

View File

@@ -62,12 +62,14 @@ const isStarRating = withRegex(
)
// Required to be > 0, because accepting zero masks many problems.
const isMetric = withRegex(/^[1-9][0-9]*[kMGTPEZY]?$/)
const isMetric = withRegex(/^([1-9][0-9]*[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY])$/)
const isMetricOpenIssues = withRegex(/^[1-9][0-9]*[kMGTPEZY]? open$/)
const isMetricOpenIssues = withRegex(
/^([1-9][0-9]*[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY]) open$/
)
const isMetricOverTimePeriod = withRegex(
/^[1-9][0-9]*[kMGTPEZY]?\/(year|month|four weeks|week|day)$/
/^([1-9][0-9]*[kMGTPEZY]?|[1-9]\.[1-9][kMGTPEZY])\/(year|month|four weeks|week|day)$/
)
const isIntegerPercentage = withRegex(/^[1-9][0-9]?%|^100%|^0%$/)

View File

@@ -56,9 +56,17 @@ function metric(n) {
for (let i = metricPrefix.length - 1; i >= 0; i--) {
const limit = metricPower[i]
if (n >= limit) {
n = Math.round(n / limit)
if (n < 1000) {
return `${n}${metricPrefix[i]}`
const scaledN = n / limit
if (scaledN < 10) {
// For "small" numbers, display one decimal digit unless it is 0.
const oneDecimalN = scaledN.toFixed(1)
if (oneDecimalN.charAt(oneDecimalN.length - 1) !== '0') {
return `${oneDecimalN}${metricPrefix[i]}`
}
}
const roundedN = Math.round(scaledN)
if (roundedN < 1000) {
return `${roundedN}${metricPrefix[i]}`
} else {
return `1${metricPrefix[i + 1]}`
}

View File

@@ -42,14 +42,24 @@ describe('Text formatters', function() {
test(metric, () => {
given(999).expect('999')
given(1000).expect('1k')
given(1100).expect('1.1k')
given(10100).expect('10k')
given(999499).expect('999k')
given(999500).expect('1M')
given(1578896212).expect('2G')
given(80000000000000).expect('80T')
given(1100000).expect('1.1M')
given(1578896212).expect('1.6G')
given(20000000000).expect('20G')
given(15788962120).expect('16G')
given(9949999999999).expect('9.9T')
given(9950000000001).expect('10T')
given(4000000000000001).expect('4P')
given(4200000000000001).expect('4.2P')
given(7100700010058000200).expect('7.1E')
given(71007000100580002000).expect('71E')
given(1000000000000000000000).expect('1Z')
given(2222222222222222222222222).expect('2Y')
given(1100000000000000000000).expect('1.1Z')
given(2222222222222222222222222).expect('2.2Y')
given(22222222222222222222222222).expect('22Y')
})
test(omitv, () => {

View File

@@ -1,6 +1,5 @@
'use strict'
const Joi = require('@hapi/joi')
const { ServiceTester } = require('../tester')
const { isMetric, isMetricOverTimePeriod } = require('../test-validators')
@@ -20,7 +19,7 @@ t.create('Plugin Downloads - Active')
.get('/plugin/installs/akismet.json')
.expectBadge({
label: 'active installs',
message: Joi.string().regex(/^[1-9][0-9]*[kMGTPEZY]\+?$/),
message: isMetric,
})
t.create('Plugin Downloads - Day')
@@ -54,7 +53,7 @@ t.create('Theme Downloads - Active')
.get('/theme/installs/twentyseventeen.json')
.expectBadge({
label: 'active installs',
message: Joi.string().regex(/^[1-9][0-9]*[kMGTPEZY]\+?$/),
message: isMetric,
})
t.create('Plugin Downloads - Total | Not Found')