diff --git a/lib/stats-tpl.js b/lib/stats-tpl.js index b9cde3ce0..47e937629 100644 --- a/lib/stats-tpl.js +++ b/lib/stats-tpl.js @@ -13,16 +13,26 @@ module.exports = { const total = metadata.packages const repos = metadata.repos + const areNull = repos.unsets || 0 + const notNull = total - areNull + const perc = (val) => (val * 100 / total).toFixed(2) + return dedent` Packages | Count | Percentage -------- | ----- | ---------- - With repository in package.json | ${total} | 100% + With repository | ${notNull} | ${perc(notNull)}% + Null repository | ${areNull} | ${perc(areNull)}% + **Total** | ${total} | ${perc(total)}% + + Providers | Count | Percentage + -------- | ----- | ---------- GitHub | ${repos.github} | ${perc(repos.github)}% GitLab | ${repos.gitlab} | ${perc(repos.gitlab)}% Bitbucket | ${repos.bitbucket} | ${perc(repos.bitbucket)}% Others | ${repos.others} | ${perc(repos.others)}% + **Total** | ${notNull} | ${perc(notNull)}% ` } diff --git a/scripts/update.js b/scripts/update.js index 47767ac8a..4078bdd87 100644 --- a/scripts/update.js +++ b/scripts/update.js @@ -49,6 +49,7 @@ const stats = { * Stats about the repos */ const repos = { + unsets: 0, github: 0, gitlab: 0, bitbucket: 0, @@ -177,12 +178,6 @@ const cache = (change) => { } const isDelete = change.deleted - const isGitUrl = change.doc && - change.doc.repository - - if (!(isDelete || isGitUrl)) { - return // not worth keeping - } const entry = { seq: change.seq, @@ -191,9 +186,13 @@ const cache = (change) => { if (isDelete) { entry.deleted = true - } else { + } + + const repo = extractRepository(change) + + if (repo) { entry.doc = { - repository: change.doc.repository + repository: repo } } @@ -226,32 +225,40 @@ const apply = (change) => { return delete packages[name] } - const url = extractUrl(change) + const changeUrl = extractUrl(change) + const parsedUrl = parseUrl(changeUrl) || null - if (!url) { + if (changeUrl && !parsedUrl) { stats.invalid += 1 return } - if (typeof curr === 'string') { - updateRepoStats(curr, -1) - stats.updates += 1 - } else { + const isInsert = typeof curr === 'undefined' + + if (isInsert) { stats.inserts += 1 + } else { + stats.updates += 1 + updateRepoStats(curr, -1) } - packages[name] = url - updateRepoStats(url, +1) + packages[name] = parsedUrl + updateRepoStats(parsedUrl, +1) +} + +const extractRepository = (change) => { + return change.doc && + change.doc.repository } /** * @return {string} - repo url */ const extractUrl = (change) => { - const repo = change.doc && - change.doc.repository - - return repo && parseUrl(repo) + const repo = extractRepository(change) + return typeof repo === 'string' + ? repo + : repo && repo.url } const urlToObject = (parse) => { @@ -275,11 +282,7 @@ const URL_PARSERS = [ plainUrl ] -const parseUrl = (repo) => { - const url = typeof repo === 'string' - ? repo - : repo.url - +const parseUrl = (url) => { if (typeof url !== 'string') { return } @@ -310,6 +313,10 @@ const TYPES = [ ] const extractType = (url) => { + if (url === null) { + return 'unsets' + } + const domain = extractDomain(url) if (domain) { diff --git a/test/metadata.js b/test/metadata.js new file mode 100644 index 000000000..36d9702a6 --- /dev/null +++ b/test/metadata.js @@ -0,0 +1,64 @@ +const describe = require('mocha').describe +const it = require('mocha').it +const expect = require('chai').expect + +const packages = require('../data/packages.json') +const metadata = require('../data/metadata.json') + +const sum = (a, b) => a + b + +describe('metadata', () => { + describe('repos', () => { + it('should match repos', () => { + const real = Object + .keys(packages) + .length + + const repos = Object + .values(metadata.repos) + .reduce(sum, 0) + + expect(repos) + .to.be.equals(real) + }) + + it('should match unsets', () => { + const real = Object + .values(packages) + .filter(url => url === null) + .length + + expect(metadata.repos.unsets || 0) + .to.be.equals(real) + }) + + it('should match urls', () => { + const real = Object + .values(packages) + .filter(Boolean) + .length + + const repos = Object + .values(metadata.repos) + .reduce(sum, 0) + + const others = repos - (metadata.repos.unsets || 0) + + expect(others) + .to.be.equals(real) + }) + }) + + describe('stats', () => { + it('should correctly count changes', () => { + const changes = metadata.stats.inserts + + metadata.stats.updates + + metadata.stats.deletes + + metadata.stats.invalid + + metadata.stats.ignored + + expect(metadata.stats.changes) + .to.be.equals(changes) + }) + }) +}) diff --git a/test/repos.js b/test/repos.js index df25f9e0f..51b8a2b6f 100644 --- a/test/repos.js +++ b/test/repos.js @@ -19,10 +19,9 @@ describe('repos', () => { it('is always a URL', function () { this.timeout(10 * 1000) - const urls = Object.values(repos) - urls.forEach(url => { - expect(isUrl(url), `${url}`).to.eq(true) - }) + for (const url of Object.values(repos)) { + expect(url === null || isUrl(url), url).to.eq(true) + } }) it('includes scoped package names', () => { diff --git a/test/stats.js b/test/stats.js index 13e2fc8ec..1b1cf816e 100644 --- a/test/stats.js +++ b/test/stats.js @@ -14,22 +14,31 @@ describe('stats', () => { it('should build the correct table', () => { const metadata = { - packages: 12, repos: { - github: 3, - gitlab: 4, - bitbucket: 6, - others: 9 + github: 1, + gitlab: 2, + bitbucket: 3, + unsets: 4, + others: 5 } } + + metadata.packages = Object + .values(metadata.repos) + .reduce((a, b) => a + b, 0) + const table = tpl.build(metadata) + expect(table) .to.be.a('string') .to.match(tpl.regex) - .to.match(/With repository in package.json \| 12 \| 100%/) - .to.match(/GitHub \| 3 \| 25\.00%/) - .to.match(/GitLab \| 4 \| 33\.33%/) - .to.match(/Bitbucket \| 6 \| 50\.00%/) - .to.match(/Others \| 9 \| 75\.00%/) + .to.match(/With repository \| 11 \| 73.33%/) + .to.match(/Null repository \| 4 \| 26.67%/) + .to.match(/\*\*Total\*\* \| 15 \| 100.00%/) + .to.match(/GitHub \| 1 \| 6.67%/) + .to.match(/GitLab \| 2 \| 13.33%/) + .to.match(/Bitbucket \| 3 \| 20.00%/) + .to.match(/Others \| 5 \| 33.33%/) + .to.match(/\*\*Total\*\* \| 11 \| 73.33%/) }) })