Commit 6ea4b35

Anton Golub <antongolub@antongolub.com>
2023-10-11 17:30:17
feat: simplify stats presenter, add evidence and tests
1 parent 8aa5fbc
Changed files (3)
src/all-badges/stars/stars.ts
@@ -3,39 +3,42 @@ import { BadgePresenter, Present } from '../../badges.js'
 export default new (class implements BadgePresenter {
   url = new URL(import.meta.url)
   badges = [
-    'stars-100',
-    'stars-500',
-    'stars-1000',
-    'stars-2000',
-    'stars-5000',
-    'stars-10000',
     'stars-20000',
+    'stars-10000',
+    'stars-5000',
+    'stars-2000',
+    'stars-1000',
+    'stars-500',
+    'stars-100',
   ] as const
   present: Present = (data, grant) => {
     let totalStars = 0
-    for (const repo of data.repos) {
-      totalStars += repo.stargazers_count || 0
-    }
-    if (totalStars >= 100) {
-      grant('stars-100', `I collected 100 stars.`)
-    }
-    if (totalStars >= 500) {
-      grant('stars-500', 'I collected 500 stars.')
-    }
-    if (totalStars >= 1000) {
-      grant('stars-1000', 'I collected 1000 stars.')
-    }
-    if (totalStars >= 2000) {
-      grant('stars-2000', 'I collected 2000 stars.')
-    }
-    if (totalStars >= 5000) {
-      grant('stars-5000', 'I collected 5000 stars.')
-    }
-    if (totalStars >= 10000) {
-      grant('stars-10000', 'I collected 10000 stars.')
-    }
-    if (totalStars >= 20000) {
-      grant('stars-20000', 'I collected 20000 stars.')
-    }
+
+    const sorted = data.repos.sort(
+      ({ stargazers_count: a = 0 }, { stargazers_count: b = 0 }) => b - a,
+    )
+    const reasonable = sorted
+      .map((repo) => {
+        if (!repo.stargazers_count) {
+          return
+        }
+        totalStars += repo.stargazers_count
+
+        return `* <a href="https://github.com/${repo.owner.login}/${repo.name}     <i>${repo.stargazers_count}</i></a>`
+      })
+      .filter(Boolean)
+
+    const text = `Repos:
+${reasonable.join('\n')}
+
+<sup>I have push, maintainer or admin permissions, so I'm definitely an author.<sup>
+`
+
+    this.badges.forEach((badge) => {
+      const limit = +badge.slice(6)
+      if (totalStars >= limit) {
+        grant(badge, `I collected ${limit} stars.`).evidence(text)
+      }
+    })
   }
 })()
test/badges.test.ts
@@ -39,6 +39,7 @@ describe('badges', () => {
       'fix-6+',
       'chore-commit',
       'delorean',
+      'covid-19',
     ]
 
     assert.deepEqual(names.sort(), expected.sort())
test/stars.test.ts
@@ -0,0 +1,91 @@
+import * as assert from 'node:assert'
+import { describe, it } from 'node:test'
+import starsPresenter from '../src/all-badges/stars/stars.js'
+import { Badge, badgeCollection } from '../src/badges.js'
+import { Data } from '../src/collect/collect.js'
+
+describe('stars', () => {
+  it('counts and renders as expected', () => {
+    const badges: Badge[] = []
+    const grant = badgeCollection(
+      badges,
+      starsPresenter.url,
+      [...starsPresenter.badges],
+      [],
+    )
+    const data: Data = {
+      user: {} as Data['user'],
+      pulls: {} as Data['pulls'],
+      issues: {} as Data['issues'],
+      repos: [
+        {
+          stargazers_count: 1000,
+          name: 'bar',
+          owner: {
+            login: 'foo',
+          },
+        },
+        {
+          stargazers_count: 2000,
+          name: 'qux',
+          owner: {
+            login: 'foo',
+          },
+        },
+      ] as Data['repos'],
+    }
+
+    starsPresenter.present(data, grant)
+
+    assert.deepEqual(badges, [
+      {
+        id: 'stars-2000',
+        desc: 'I collected 2000 stars.',
+        body:
+          'Repos:\n' +
+          '* <a href="https://github.com/foo/qux     <i>2000</i></a>\n' +
+          '* <a href="https://github.com/foo/bar     <i>1000</i></a>\n' +
+          '\n' +
+          "<sup>I have push, maintainer or admin permissions, so I'm definitely an author.<sup>\n",
+        image:
+          'https://github.com/my-badges/my-badges/blob/master/src/all-badges/stars/stars-2000.png?raw=true',
+      },
+      {
+        id: 'stars-1000',
+        desc: 'I collected 1000 stars.',
+        body:
+          'Repos:\n' +
+          '* <a href="https://github.com/foo/qux     <i>2000</i></a>\n' +
+          '* <a href="https://github.com/foo/bar     <i>1000</i></a>\n' +
+          '\n' +
+          "<sup>I have push, maintainer or admin permissions, so I'm definitely an author.<sup>\n",
+        image:
+          'https://github.com/my-badges/my-badges/blob/master/src/all-badges/stars/stars-1000.png?raw=true',
+      },
+      {
+        id: 'stars-500',
+        desc: 'I collected 500 stars.',
+        body:
+          'Repos:\n' +
+          '* <a href="https://github.com/foo/qux     <i>2000</i></a>\n' +
+          '* <a href="https://github.com/foo/bar     <i>1000</i></a>\n' +
+          '\n' +
+          "<sup>I have push, maintainer or admin permissions, so I'm definitely an author.<sup>\n",
+        image:
+          'https://github.com/my-badges/my-badges/blob/master/src/all-badges/stars/stars-500.png?raw=true',
+      },
+      {
+        id: 'stars-100',
+        desc: 'I collected 100 stars.',
+        body:
+          'Repos:\n' +
+          '* <a href="https://github.com/foo/qux     <i>2000</i></a>\n' +
+          '* <a href="https://github.com/foo/bar     <i>1000</i></a>\n' +
+          '\n' +
+          "<sup>I have push, maintainer or admin permissions, so I'm definitely an author.<sup>\n",
+        image:
+          'https://github.com/my-badges/my-badges/blob/master/src/all-badges/stars/stars-100.png?raw=true',
+      },
+    ])
+  })
+})