Repository: paularmstrong/build-tracker
Pull request #129 (2020-02-18 16:57:25)

Add `defaultSizeKey`
<!--
Thank you so much for contributing to open source and the Build Tracker project!
-->

# Problem

Re. https://github.com/paularmstrong/build-tracker/issues/14#issuecomment-587124783

# 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/docs/docs/packages/server.md b/docs/docs/packages/server.md
index d46f593..25f1fb0 100644
--- a/docs/docs/packages/server.md
+++ b/docs/docs/packages/server.md
@@ -183,6 +183,10 @@ interface Handlers {
 
 #### `port?: number`
 
+#### `defaultSizeKey?: string`
+
+The default size type used to represent files. For example, `gzip` or `brotli`.
+
 ### Database integration
 
 The following options should generally be handled by a [Build Tracker plugin](/docs/plugins). You can always override them or write your own custom queries and DB setup if you like.
diff --git a/src/app/src/store/reducer.ts b/src/app/src/store/reducer.ts
index 9c9a699..d820dcc 100644
--- a/src/app/src/store/reducer.ts
+++ b/src/app/src/store/reducer.ts
@@ -46,7 +46,11 @@ export default function reducer(state: State, action: Actions): State {
 
       const graphType = builds.length <= 10 ? GraphType.STACKED_BAR : state.graphType;
 
-      const sizeKey = comparator.sizeKeys.includes(state.sizeKey) ? state.sizeKey : comparator.sizeKeys[0];
+      const sizeKey = comparator.sizeKeys.includes(state.sizeKey)
+        ? state.sizeKey
+        : comparator.sizeKeys.includes(state.defaultSizeKey)
+        ? state.defaultSizeKey
+        : comparator.sizeKeys[0];
       return { ...state, activeComparator, activeArtifacts, builds, comparator, graphType, sizeKey };
     }
 
diff --git a/src/app/src/store/types.ts b/src/app/src/store/types.ts
index 6398d0f..96c34d5 100644
--- a/src/app/src/store/types.ts
+++ b/src/app/src/store/types.ts
@@ -34,6 +34,7 @@ export interface State {
   hoveredArtifacts: Array<string>;
   name: string;
   snacks: Array<string>;
+  defaultSizeKey?: string;
   sizeKey: string;
   url: string;
 }
diff --git a/src/server/src/server.ts b/src/server/src/server.ts
index d00636d..a0350c9 100644
--- a/src/server/src/server.ts
+++ b/src/server/src/server.ts
@@ -41,7 +41,8 @@ export const props = (config: AppConfig, url: string): RequestHandler => (
     url,
     artifactConfig: Object.assign({}, { budgets: {}, filters: [], groups: [] }, config.artifacts || {}),
     hideAttribution: !!config.hideAttribution,
-    name: config.name || 'Build Tracker'
+    name: config.name || 'Build Tracker',
+    defaultSizeKey: config.defaultSizeKey
   };
   next();
 };
diff --git a/src/types/src/index.ts b/src/types/src/index.ts
index 196206f..05445e6 100644
--- a/src/types/src/index.ts
+++ b/src/types/src/index.ts
@@ -73,4 +73,5 @@ export interface AppConfig {
   budgets?: Array<Budget>;
   hideAttribution?: boolean;
   name?: string;
+  defaultSizeKey?: string;
 }


Test patch:
diff --git a/src/app/src/store/__tests__/reducer.test.ts b/src/app/src/store/__tests__/reducer.test.ts
index b023354..d59831b 100644
--- a/src/app/src/store/__tests__/reducer.test.ts
+++ b/src/app/src/store/__tests__/reducer.test.ts
@@ -23,6 +23,7 @@ const initialState: State = Object.freeze({
   hideAttribution: false,
   name: 'Tacos!',
   snacks: [],
+  defaultSizeKey: 'stat',
   sizeKey: '',
   url: 'https://build-tracker.local'
 });
@@ -90,8 +91,16 @@ describe('reducer', () => {
       expect(state.sizeKey).toBe('stat');
     });
 
-    test('resets the sizeKey if it the current is not in the new set', () => {
+    test('resets the sizeKey to the default if the current is not in the new set', () => {
       const state = reducer({ ...initialState, sizeKey: 'foobar' }, Actions.setBuilds([buildA, buildB]));
+      expect(state.sizeKey).toBe('stat');
+    });
+
+    test('resets the sizeKey to the first in list if both the current and the default are not in the new set', () => {
+      const state = reducer(
+        { ...initialState, defaultSizeKey: 'abc', sizeKey: 'foobar' },
+        Actions.setBuilds([buildA, buildB])
+      );
       expect(state.sizeKey).toBe('gzip');
     });