-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added chartjs data visualizations. Added cli options support, includi…
…ng visualization for category totals overall, and visualization for category totals per file type.
- Loading branch information
1 parent
e21fcd3
commit 3e7a25b
Showing
14 changed files
with
540 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,4 +38,4 @@ testem.log | |
.DS_Store | ||
Thumbs.db | ||
hd-tracker/ | ||
/hd-tracker | ||
/hd-tracker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
#!/usr/bin/env node | ||
export * from './lib'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import yargs = require('yargs'); | ||
import { ChartConfig } from './models/chart-config'; | ||
import { hideBin } from 'yargs/helpers'; | ||
|
||
interface RawArgs { | ||
root?: string; | ||
config?: string; | ||
init?: boolean; | ||
chart?: ChartConfig | ||
} | ||
|
||
export interface Args extends RawArgs { | ||
chart: ChartConfig | ||
} | ||
|
||
const parsedArgv: RawArgs = yargs(hideBin(global.process.argv)).argv as RawArgs; | ||
|
||
// set a default chart config instance from cli options | ||
parsedArgv.chart = new ChartConfig(parsedArgv.chart); | ||
|
||
export const argv = parsedArgv as Args; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { argv } from '../argv'; | ||
import { ChartConfig } from './chart-config'; | ||
|
||
|
||
describe('ChartConfig', () => { | ||
it('should be default chart configuration on argv', () => { | ||
expect(argv.chart).toStrictEqual(new ChartConfig()); | ||
}); | ||
|
||
const fakeCliOptions = { | ||
perCategoryAndFileType: true, | ||
perCategoryTotals: false, | ||
width: 42, | ||
height: 42, | ||
bg: 'negro', | ||
title: 'Grine-DING', | ||
xAxisLabel: 'tomorrows', | ||
yAxisLabel: 'weather', | ||
overwrite: false, | ||
outFile: 'flibbidy-giblets.png', | ||
} as ChartConfig; | ||
|
||
const defaultInstance = new ChartConfig(); | ||
|
||
// loop over all public keys to set key differently | ||
Object.keys(fakeCliOptions).forEach((keyToTest) => { | ||
|
||
const instantiatedViaCli = new ChartConfig({ [keyToTest]: fakeCliOptions[keyToTest] } as any); | ||
|
||
it(`should override default '${keyToTest}: ${defaultInstance[keyToTest]}' value with '${keyToTest}: ${instantiatedViaCli[keyToTest]}'`, () => { | ||
expect(defaultInstance[keyToTest]).not.toEqual(instantiatedViaCli[keyToTest]); | ||
}); | ||
|
||
// loop over all remaining keys after having set one key different | ||
Object.keys(fakeCliOptions).forEach((otherKey) => { | ||
if (otherKey === keyToTest) { return; } | ||
|
||
// testing differing keys; values should match | ||
it(`should be default '${otherKey}: ${defaultInstance[otherKey]}' value with '${otherKey}: ${instantiatedViaCli[otherKey]}'`, () => { | ||
expect(defaultInstance[otherKey]).toEqual(instantiatedViaCli[otherKey]); | ||
}); | ||
}); | ||
}) | ||
|
||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
export class ChartConfig { | ||
private _perCategoryAndFileType = false; | ||
private _perCategoryTotals = true; | ||
private _width = 1200; | ||
private _height = 800; | ||
private _bg = 'white'; | ||
private _title = 'Migration Progress LOC'; | ||
private _xAxisLabel = 'Date'; | ||
private _yAxisLabel = 'Totals'; | ||
private _overwrite = true; | ||
private _outFile = 'viz.png'; | ||
|
||
get perCategoryAndFileType(): boolean { | ||
// if false, use false; false !== undefined | ||
return this._cliOptions.perCategoryAndFileType !== undefined ? | ||
this._cliOptions.perCategoryAndFileType : | ||
this._perCategoryAndFileType; | ||
} | ||
|
||
get perCategoryTotals(): boolean { | ||
// if false, use false; false !== undefined | ||
return this._cliOptions.perCategoryTotals !== undefined ? | ||
this._cliOptions.perCategoryTotals: | ||
this._perCategoryTotals; | ||
} | ||
|
||
get width(): number { | ||
// if set and non-numeric | ||
if (this._cliOptions.width !== undefined && isNaN(Number(this._cliOptions.width))) { | ||
throw Error('--chart.width must be a number'); | ||
} | ||
// if unset or numeric | ||
return this._cliOptions.width !== undefined ? | ||
this._cliOptions.width: | ||
this._width; | ||
} | ||
|
||
get height(): number { | ||
// if set and non-numeric | ||
if (this._cliOptions.height !== undefined && isNaN(Number(this._cliOptions.height))) { | ||
throw Error('--chart.height must be a number'); | ||
} | ||
// if unset or numeric | ||
return this._cliOptions.height !== undefined ? | ||
this._cliOptions.height: | ||
this._height; | ||
} | ||
|
||
get bg(): string { | ||
return this._cliOptions.bg ? | ||
this._cliOptions.bg: | ||
this._bg; | ||
} | ||
|
||
get title(): string { | ||
return this._cliOptions.title ? | ||
this._cliOptions.title: | ||
this._title; | ||
} | ||
|
||
get xAxisLabel(): string { | ||
return this._cliOptions.xAxisLabel ? | ||
this._cliOptions.xAxisLabel: | ||
this._xAxisLabel; | ||
} | ||
|
||
get yAxisLabel(): string { | ||
return this._cliOptions.yAxisLabel ? | ||
this._cliOptions.yAxisLabel: | ||
this._yAxisLabel; | ||
} | ||
|
||
get overwrite(): boolean { | ||
return this._cliOptions.overwrite !== undefined ? | ||
this._cliOptions.overwrite: | ||
this._overwrite; | ||
} | ||
|
||
get outFile(): string { | ||
return this._cliOptions.outFile ? | ||
this._cliOptions.outFile: | ||
this._outFile; | ||
} | ||
|
||
constructor(private _cliOptions: ChartConfig = {} as ChartConfig) { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export type VizDataset = { | ||
label: string; | ||
data: number[]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { VizDataset } from './viz-dataset' | ||
|
||
export type VizLabelsDatasets = { | ||
labels: string[], | ||
datasets: VizDataset[], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { argv } from './argv'; | ||
import { ChartConfig } from './models/chart-config'; | ||
import { TrackerChart } from './tracker-chart'; | ||
|
||
|
||
describe('TrackerChart', () => { | ||
|
||
describe('ctor', () => { | ||
let chart; | ||
beforeEach(() => { | ||
chart = new TrackerChart(argv.chart, [], 'foo') | ||
}); | ||
|
||
it('should have default _config', () => { | ||
expect((chart as any)._config).toStrictEqual(new ChartConfig()); | ||
}); | ||
|
||
it('should have empty _allProcessResults', () => { | ||
expect((chart as any)._allProcessResults).toStrictEqual([]); | ||
}); | ||
|
||
it('should have foo _dateFormat', () => { | ||
expect((chart as any)._dateFormat).toStrictEqual('foo'); | ||
}); | ||
}); | ||
|
||
describe('private methods', () => { | ||
let spyChart: TrackerChart; | ||
let ogGetDataAndLabels; | ||
let getDataAndLabelsSpy: jest.SpyInstance; | ||
let getTotalsPerCategorySpy: jest.SpyInstance; | ||
let getTotalsPerFileTypePerCategorySpy: jest.SpyInstance; | ||
let generateGraphImageFileSpy: jest.SpyInstance; | ||
const noop = () => { undefined }; | ||
beforeEach(() => { | ||
spyChart = new TrackerChart(argv.chart, [1] as any, 'foo'); | ||
ogGetDataAndLabels = (spyChart as any).getDataAndLabels; | ||
getDataAndLabelsSpy = jest.spyOn((spyChart as any), 'getDataAndLabels').mockImplementation(noop); | ||
getTotalsPerCategorySpy = jest.spyOn((spyChart as any), 'getTotalsPerCategory').mockImplementation(noop); | ||
getTotalsPerFileTypePerCategorySpy = jest.spyOn((spyChart as any), 'getTotalsPerFileTypePerCategory').mockImplementation(noop); | ||
generateGraphImageFileSpy = jest.spyOn((spyChart as any), 'generateGraphImageFile').mockImplementation(noop); | ||
|
||
}); | ||
|
||
afterEach(() => { | ||
getDataAndLabelsSpy.mockReset(); | ||
getTotalsPerCategorySpy.mockReset(); | ||
getTotalsPerFileTypePerCategorySpy.mockReset(); | ||
generateGraphImageFileSpy.mockReset(); | ||
}); | ||
|
||
it('calls getDataAndLabels inside writeTo', () => { | ||
spyChart.writeTo(''); | ||
expect(getDataAndLabelsSpy).toHaveBeenCalledWith([1], 'total'); | ||
}); | ||
|
||
it('calls generateGraphImageFileSpy inside writeTo', () => { | ||
spyChart.writeTo(''); | ||
expect(generateGraphImageFileSpy).toHaveBeenCalledWith('', undefined); | ||
}); | ||
|
||
it('calls getTotalsPerCategory inside getDataLabels', () => { | ||
(spyChart as any).getDataAndLabels = ogGetDataAndLabels; | ||
(spyChart as any).getDataAndLabels([1], 'total'); | ||
expect(getTotalsPerCategorySpy).toHaveBeenCalledWith([1], 'total'); | ||
(spyChart as any).getDataAndLabels = getDataAndLabelsSpy; | ||
}); | ||
|
||
it('calls getTotalsPerFileTypePerCategory inside getDataLabels', () => { | ||
(spyChart as any)._config._perCategoryTotals = false; | ||
(spyChart as any)._config._perCategoryAndFileType = true; | ||
(spyChart as any).getDataAndLabels = ogGetDataAndLabels; | ||
(spyChart as any).getDataAndLabels([1], 'total'); | ||
expect(getTotalsPerFileTypePerCategorySpy).toHaveBeenCalledWith([1], 'total'); | ||
(spyChart as any).getDataAndLabels = getDataAndLabelsSpy; | ||
}); | ||
|
||
it('calls getTotalsPerCategory inside getDataLabels by default', () => { | ||
(spyChart as any)._config._perCategoryTotals = undefined; | ||
(spyChart as any)._config._perCategoryAndFileType = undefined; | ||
(spyChart as any).getDataAndLabels = ogGetDataAndLabels; | ||
(spyChart as any).getDataAndLabels([1], 'total'); | ||
expect(getTotalsPerCategorySpy).toHaveBeenCalledWith([1], 'total'); | ||
(spyChart as any).getDataAndLabels = getDataAndLabelsSpy; | ||
}); | ||
|
||
}); | ||
|
||
}); |
Oops, something went wrong.