Repository: paularmstrong/build-tracker
Pull request #115 (2020-02-17 14:07:35)

Handle 0 rows
<!--
Thank you so much for contributing to open source and the Build Tracker project!
-->

# Problem

See the failing test. Previously this would throw an exception:

```
  ● BuildComparator › toMarkdown › does not error when there are 0 rows

    TypeError: Cannot read property 'map' of undefined

      412 |     const rows = this.getStringFormattedRows(formatTotal, formatDelta, sizeKey, artifactFilter);
      413 |
    > 414 |     return markdownTable([header, ...groups, ...rows], { align: rows[0].map((_, i) => (i === 0 ? 'l' : 'r')) });
          |                                                                         ^
      415 |   }
      416 |
      417 |   public toCsv({

      at BuildComparator.Object.<anonymous>.BuildComparator.toMarkdown (src/index.ts:414:73)
      at Object.<anonymous> (src/__tests__/index.test.ts:351:25)
```

# Solution

<!--
When trying to solve more solutions with Build Tracker, please keep in mind some of the following goals of the project:
* Be lightweight: small package sizes (single-digit KiBs, gzipped)
* Be easy: too many options in an API can become confusing
* Be clear: the intended purpose of every method should be as obvious as possible
* Is it easy to do this in "userland"? Would it be better off done there?
-->

Explain your approach. Sometimes it helps to justify your approach against some others that you didn't choose to explain why yours is better.

# TODO

- [x] 🤓 Add & update tests (always try to _increase_ test coverage)
- [x] 🔬 Ensure CI is passing (`yarn lint:ci`, `yarn test`, `yarn tsc:ci`)
- [x] 📖 Update relevant documentation



Patch:
diff --git a/src/comparator/src/index.ts b/src/comparator/src/index.ts
index a2658df..8f56ee9 100644
--- a/src/comparator/src/index.ts
+++ b/src/comparator/src/index.ts
@@ -411,7 +411,9 @@ export default class BuildComparator {
     const groups = this.getStringFormattedGroups(formatTotal, formatDelta, sizeKey);
     const rows = this.getStringFormattedRows(formatTotal, formatDelta, sizeKey, artifactFilter);
 
-    return markdownTable([header, ...groups, ...rows], { align: rows[0].map((_, i) => (i === 0 ? 'l' : 'r')) });
+    const allRows = [header, ...groups, ...rows];
+
+    return markdownTable(allRows, { align: allRows[0].map((_, i) => (i === 0 ? 'l' : 'r')) });
   }
 
   public toCsv({


Test patch:
diff --git a/src/comparator/src/__tests__/index.test.ts b/src/comparator/src/__tests__/index.test.ts
index 749f696..02313a2 100644
--- a/src/comparator/src/__tests__/index.test.ts
+++ b/src/comparator/src/__tests__/index.test.ts
@@ -20,6 +20,14 @@ const build1 = new Build(
     { name: 'tacos', hash: 'abc', sizes: { stat: 123, gzip: 45 } }
   ]
 );
+// Same as build 1 but different revision
+const build1b = new Build(
+  { branch: 'master', revision: '1234567abcdeg', parentRevision: '1234567abcdef', timestamp: 1234567 },
+  [
+    { name: 'burritos', hash: 'abc', sizes: { stat: 456, gzip: 90 } },
+    { name: 'tacos', hash: 'abc', sizes: { stat: 123, gzip: 45 } }
+  ]
+);
 
 const build2 = new Build(
   { branch: 'master', revision: '8901234abcdef', parentRevision: 'abcdef', timestamp: 8901234 },
@@ -338,6 +346,15 @@ describe('BuildComparator', () => {
       `);
     });
 
+    test('handles 0 artifacts', () => {
+      const comparator = new BuildComparator({ builds: [build1, build1b] });
+      expect(comparator.toMarkdown({ artifactFilter: () => false })).toMatchInlineSnapshot(`
+      "|     |  1234567 |  1234567 |           Δ1 |
+      | :-- | -------: | -------: | -----------: |
+      | All | 0.13 KiB | 0.13 KiB | 0 KiB (0.0%) |"
+      `);
+    });
+
     test('can specify a different size key', () => {
       const comparator = new BuildComparator({ builds: [build1, build2] });
       expect(comparator.toMarkdown({ sizeKey: 'stat' })).toMatchInlineSnapshot(`