Skip to content

Commit cb96150

Browse files
author
Simon Renoult
committed
refactor: simplify Statistics interface
1 parent fc20b41 commit cb96150

File tree

4 files changed

+56
-71
lines changed

4 files changed

+56
-71
lines changed

src/io/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Cli from "./cli";
22
import Output from "./output";
3-
import { Options, Path } from "../lib/types";
3+
import { Options } from "../lib/types";
44
import Statistics from "../lib";
55
import { execSync } from "child_process";
66
import { existsSync } from "fs";
@@ -12,7 +12,7 @@ export default async function main(): Promise<void> {
1212
assertGitIsInstalled();
1313
assertIsGitRootDirectory(options.directory);
1414

15-
const statistics: Map<Path, Statistics> = await Statistics.compute(options);
15+
const statistics = await Statistics.compute(options);
1616
Cli.cleanup(options);
1717
Output.render(statistics, options);
1818
}

src/io/output.ts

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as Table from "cli-table3";
22

33
import Statistics from "../lib/statistics";
4-
import { Options, Path } from "../lib/types";
4+
import { Options } from "../lib/types";
55
import { buildDebugger, withDuration } from "../utils";
66

77
const internal = { debug: buildDebugger("output") };
@@ -10,25 +10,20 @@ export default {
1010
render: (...args: any[]): void => withDuration(render, args, internal.debug),
1111
};
1212

13-
function render(
14-
statisticsPerPath: Map<Path, Statistics>,
15-
options: Options
16-
): void {
17-
const values = Array.from(statisticsPerPath.values());
18-
13+
function render(statistics: Statistics[], options: Options): void {
1914
let stdout;
2015
switch (options.format) {
2116
case "table":
22-
stdout = toTable(values);
17+
stdout = toTable(statistics);
2318
break;
2419
case "json":
25-
stdout = toJson(values);
20+
stdout = toJson(statistics);
2621
break;
2722
case "csv":
28-
stdout = toCSV(values);
23+
stdout = toCSV(statistics);
2924
break;
3025
default:
31-
stdout = toTable(values);
26+
stdout = toTable(statistics);
3227
}
3328

3429
console.log(stdout);

src/lib/statistics.ts

+35-44
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,23 @@ export default class Statistics {
2424

2525
private readonly directories: string[];
2626

27-
public static async compute(
28-
options: Options
29-
): Promise<Map<Path, Statistics>> {
27+
public static async compute(options: Options): Promise<Statistics[]> {
3028
internal.debug(`invoked with options: ${JSON.stringify(options)}`);
3129
internal.debug(`using cwd: ${process.cwd()}`);
3230

3331
const churns = await Churn.compute(options);
3432
const paths = Array.from(churns.keys());
3533
const complexities = await Complexity.compute(paths, options);
3634

37-
const statistics = paths.map(Statistics.toStatistics(churns, complexities));
35+
const statisticsForFiles: Statistics[] = paths.map(
36+
Statistics.toStatistics(churns, complexities)
37+
);
3838

39-
const mapOfStatistics = options.directories
40-
? Statistics.toDirectoryMap(statistics)
41-
: Statistics.toFileMap(statistics);
39+
const result = options.directories
40+
? Statistics.buildDirectoriesStatistics(statisticsForFiles)
41+
: statisticsForFiles;
4242

43-
return new Map(
44-
[...mapOfStatistics.entries()]
45-
.sort(([, v1], [, v2]) => sort(options.sort)(v1, v2))
46-
.filter(([, v], index) => limit(options.limit)(v, index))
47-
);
43+
return result.sort(sort(options.sort)).filter(limit(options.limit));
4844
}
4945

5046
public static toStatistics(
@@ -58,44 +54,18 @@ export default class Statistics {
5854
};
5955
}
6056

61-
private constructor(path: Path, churn: number, complexity: number) {
62-
this.path = path;
63-
this.churn = churn;
64-
this.complexity = complexity;
65-
this.directories = this.findDirectoriesForFile(path);
66-
this.score = this.churn * this.complexity;
67-
}
68-
69-
private findDirectoriesForFile(path: string): string[] {
70-
const directories: string[] = [];
71-
const pathChunks = NodePath.parse(path).dir.split(NodePath.sep);
72-
pathChunks.forEach((chunk) => {
73-
const parentDir = directories.slice(-1);
74-
const directory = parentDir.length
75-
? parentDir + NodePath.sep + chunk
76-
: chunk;
77-
directories.push(directory);
78-
});
79-
return directories.filter((d) => d.length > 0);
80-
}
81-
82-
private static toFileMap(statistics: Statistics[]): Map<Path, Statistics> {
83-
return statistics.reduce((map: Map<Path, Statistics>, statistics) => {
84-
map.set(statistics.path, statistics);
85-
return map;
86-
}, new Map());
87-
}
88-
89-
private static toDirectoryMap(
90-
allStatistics: Statistics[]
91-
): Map<string, Statistics> {
92-
return allStatistics.reduce((map, statisticsForFile) => {
57+
private static buildDirectoriesStatistics(
58+
statisticsForFiles: Statistics[]
59+
): Statistics[] {
60+
const map = statisticsForFiles.reduce((map, statisticsForFile) => {
9361
statisticsForFile.directories.forEach((directoryForFile) => {
9462
computeStatisticsForDirectory(map, directoryForFile, statisticsForFile);
9563
});
9664
return map;
9765
}, new Map<string, Statistics>());
9866

67+
return [...map.values()];
68+
9969
function computeStatisticsForDirectory(
10070
map: Map<string, Statistics>,
10171
dir: string,
@@ -112,6 +82,27 @@ export default class Statistics {
11282
}
11383
}
11484

85+
private constructor(path: Path, churn: number, complexity: number) {
86+
this.path = path;
87+
this.churn = churn;
88+
this.complexity = complexity;
89+
this.directories = this.findDirectoriesForFile(path);
90+
this.score = this.churn * this.complexity;
91+
}
92+
93+
private findDirectoriesForFile(path: string): string[] {
94+
const directories: string[] = [];
95+
const pathChunks = NodePath.parse(path).dir.split(NodePath.sep);
96+
pathChunks.forEach((chunk) => {
97+
const parentDir = directories.slice(-1);
98+
const directory = parentDir.length
99+
? parentDir + NodePath.sep + chunk
100+
: chunk;
101+
directories.push(directory);
102+
});
103+
return directories.filter((d) => d.length > 0);
104+
}
105+
115106
public toState(): IStatistics {
116107
return {
117108
path: this.path,

test/lib/statistics.test.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ describe("Statistics", () => {
3232
const result = await Statistics.compute(options);
3333

3434
// Then
35-
const statistics = [...result.values()].map((s) => s.toState());
36-
35+
const statistics = result.map((s) => s.toState());
3736
expect(statistics).to.have.length(3);
3837
});
3938
});
@@ -53,7 +52,7 @@ describe("Statistics", () => {
5352

5453
// When
5554
const result = await Statistics.compute(options);
56-
const statistics = [...result.values()].map((s) => s.toState());
55+
const statistics = result.map((s) => s.toState());
5756

5857
// Then
5958
expect(statistics).to.deep.equal([
@@ -85,7 +84,7 @@ describe("Statistics", () => {
8584

8685
// When
8786
const result = await Statistics.compute(options);
88-
const statistics = [...result.values()].map((s) => s.toState());
87+
const statistics = result.map((s) => s.toState());
8988

9089
// Then
9190
expect(statistics).to.deep.equal([
@@ -117,7 +116,7 @@ describe("Statistics", () => {
117116

118117
// When
119118
const result = await Statistics.compute(options);
120-
const statistics = [...result.values()].map((s) => s.toState());
119+
const statistics = result.map((s) => s.toState());
121120

122121
// Then
123122
expect(statistics).to.deep.equal([
@@ -144,7 +143,7 @@ describe("Statistics", () => {
144143

145144
// When
146145
const result = await Statistics.compute(options);
147-
const statistics = [...result.values()].map((s) => s.toState());
146+
const statistics = result.map((s) => s.toState());
148147

149148
// Then
150149
expect(statistics).to.deep.equal([
@@ -192,7 +191,7 @@ describe("Statistics", () => {
192191

193192
// When
194193
const result = await Statistics.compute(options);
195-
const statistics = [...result.values()].map((s) => s.toState());
194+
const statistics = result.map((s) => s.toState());
196195

197196
// Then
198197
expect(statistics).to.deep.equal([
@@ -233,7 +232,7 @@ describe("Statistics", () => {
233232

234233
// When
235234
const result = await Statistics.compute(options);
236-
const statistics = [...result.values()].map((s) => s.toState());
235+
const statistics = result.map((s) => s.toState());
237236

238237
// Then
239238
expect(statistics).to.deep.equal([
@@ -271,7 +270,7 @@ describe("Statistics", () => {
271270

272271
// When
273272
const result = await Statistics.compute(options);
274-
const statistics = [...result.values()].map((s) => s.toState());
273+
const statistics = result.map((s) => s.toState());
275274

276275
// Then
277276
expect(statistics).to.deep.equal([
@@ -311,7 +310,7 @@ describe("Statistics", () => {
311310

312311
// When
313312
const result = await Statistics.compute(options);
314-
const statistics = [...result.values()].map((s) => s.toState());
313+
const statistics = result.map((s) => s.toState());
315314

316315
// Then
317316
expect(statistics).to.deep.equal([
@@ -340,7 +339,7 @@ describe("Statistics", () => {
340339

341340
// When
342341
const result = await Statistics.compute(options);
343-
const statistics = [...result.values()].map((s) => s.toState());
342+
const statistics = result.map((s) => s.toState());
344343

345344
// Then
346345
expect(statistics).to.deep.equal([
@@ -379,7 +378,7 @@ describe("Statistics", () => {
379378

380379
// When
381380
const result = await Statistics.compute(options);
382-
const statistics = [...result.values()].map((s) => s.toState());
381+
const statistics = result.map((s) => s.toState());
383382

384383
// Then
385384
expect(statistics).to.deep.equal([
@@ -422,7 +421,7 @@ describe("Statistics", () => {
422421

423422
// When
424423
const result = await Statistics.compute(options);
425-
const statistics = [...result.values()].map((s) => s.toState());
424+
const statistics = result.map((s) => s.toState());
426425

427426
// Then
428427
expect(statistics).to.deep.equal([
@@ -465,7 +464,7 @@ describe("Statistics", () => {
465464

466465
// When
467466
const result = await Statistics.compute(options);
468-
const statistics = [...result.values()].map((s) => s.toState());
467+
const statistics = result.map((s) => s.toState());
469468

470469
// Then
471470
expect(statistics).to.deep.equal([

0 commit comments

Comments
 (0)