Skip to content

Commit 17ea3b9

Browse files
authored
refactor: replace html-minifier with html-minifier-terser to remove dependency on uglify and support ES6 and newer (#10)
1 parent 997a5cd commit 17ea3b9

6 files changed

Lines changed: 158 additions & 96 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
},
3333
"homepage": "https://github.com/fugle-dev/fugle-backtest-node#readme",
3434
"dependencies": {
35-
"html-minifier": "^4.0.0",
35+
"html-minifier-terser": "^7.2.0",
3636
"lodash": "^4.17.21",
3737
"luxon": "^3.2.1",
3838
"open": "^8.4.1"
@@ -41,6 +41,7 @@
4141
"@commitlint/cli": "^16.2.1",
4242
"@commitlint/config-conventional": "^16.2.1",
4343
"@types/html-minifier": "^4.0.2",
44+
"@types/html-minifier-terser": "^7.0.2",
4445
"@types/jest": "^27.0.1",
4546
"@types/lodash": "^4.14.191",
4647
"@types/luxon": "^3.2.0",

src/plotting.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as fs from 'fs';
22
import * as assert from 'assert';
33
import * as open from 'open';
4-
import { minify } from 'html-minifier';
4+
import { minify } from 'html-minifier-terser';
55
import { Stats } from './stats';
66
import { PlottingOptions } from './interfaces';
77

@@ -16,17 +16,14 @@ export class Plotting {
1616
this.filename = options?.filename?.toLowerCase() ?? 'output.html';
1717
}
1818

19-
public plot() {
20-
const html = minify(this.createHTML(), {
21-
collapseWhitespace: true,
22-
removeComments: true,
23-
collapseBooleanAttributes: true,
24-
useShortDoctype: true,
25-
removeEmptyAttributes: true,
26-
removeOptionalTags: true,
27-
minifyJS: true
28-
});
29-
const outputFile = this.filename.endsWith('.html') ? `./${this.filename}` : `./${this.filename}.html`;
19+
public async getHTML() {
20+
return await minify(this.createHTML());
21+
}
22+
23+
public async plot() {
24+
const html = await minify(this.createHTML());
25+
let outputFile = this.filename.startsWith('/') || this.filename.startsWith('./') ? this.filename : `./${this.filename}`;
26+
if (! outputFile.endsWith('.html')) outputFile = outputFile + '.html';
3027
fs.writeFileSync(outputFile, html);
3128

3229
if (this.openBrowser) open(outputFile);

src/stats.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,18 @@ export class Stats {
172172
this.results.print();
173173
}
174174

175-
public plot() {
175+
public async plot() {
176176
if (!this.results) {
177177
throw new Error('No stats results');
178178
}
179-
new Plotting(this, { openBrowser: this.options.openBrowser, filename: this.options.filename }).plot();
179+
await new Plotting(this, { openBrowser: this.options.openBrowser, filename: this.options.filename }).plot();
180+
}
181+
182+
public async toHTML() {
183+
if (!this.results) {
184+
throw new Error('No stats results');
185+
}
186+
return await new Plotting(this).getHTML();
180187
}
181188

182189
private computeExposureTime(index: string[], tradeLog: DataFrame) {

test/plotting.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import * as open from 'open';
2-
import { minify } from 'html-minifier';
2+
import { minify } from 'html-minifier-terser';
33
import { Plotting } from '../src/plotting';
44
import { Backtest } from '../src/backtest';
55
import { Stats } from '../src/stats';
66
import { SmaCross } from './sma-cross.strategy';
77

88
jest.mock('fs');
99
jest.mock('open');
10-
jest.mock('html-minifier');
10+
jest.mock('html-minifier-terser');
1111

1212
describe('Plotting', () => {
1313
let backtest: Backtest;
@@ -47,18 +47,18 @@ describe('Plotting', () => {
4747
});
4848

4949
describe('.plot()', () => {
50-
it('should create the HTML file with minified content', () => {
51-
const options = { openBrowser: false, filename: 'test.html' };
50+
it('should create the HTML file with minified content', async () => {
51+
const options = {openBrowser: false, filename: 'test.html'};
5252
const plotting = new Plotting(stats, options);
53-
plotting.plot();
53+
await plotting.plot();
5454
expect(minify).toHaveBeenCalled();
5555
expect(open).not.toBeCalled();
5656
});
5757

58-
it('should create the HTML file with minified content and open it in the browser', () => {
59-
const options = { openBrowser: true, filename: 'test.html' };
58+
it('should create the HTML file with minified content and open it in the browser', async () => {
59+
const options = {openBrowser: true, filename: 'test.html'};
6060
const plotting = new Plotting(stats, options);
61-
plotting.plot();
61+
await plotting.plot();
6262
expect(minify).toHaveBeenCalled();
6363
expect(open).toHaveBeenCalledWith(`./${options.filename}`);
6464
});

test/stats.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,19 @@ describe('Stats', () => {
7373
});
7474

7575
describe('.plot()', () => {
76-
it('should plot the equity curve', () => {
77-
const stats = new Stats(data, strategy, equity, trades, { riskFreeRate: 0 });
76+
it('should plot the equity curve', async () => {
77+
const stats = new Stats(data, strategy, equity, trades, {riskFreeRate: 0});
7878
stats.compute();
7979
Plotting.prototype.plot = jest.fn();
80-
stats.plot();
80+
await stats.plot();
8181
expect(Plotting.prototype.plot).toBeCalled();
8282
});
8383

84-
it('should throw error when missing results', () => {
85-
expect(() => {
86-
const stats = new Stats(data, strategy, equity, trades, { riskFreeRate: 0 });
87-
stats.plot();
88-
}).toThrow(Error);
84+
it('should throw error when missing results', async () => {
85+
await expect(async () => {
86+
const stats = new Stats(data, strategy, equity, trades, {riskFreeRate: 0});
87+
await stats.plot();
88+
}).rejects.toThrow(Error);
8989
});
9090
});
9191
});

0 commit comments

Comments
 (0)