Skip to content

Commit 2a69384

Browse files
committed
jest half-set-up (still errors with esm)
1 parent d63dc96 commit 2a69384

17 files changed

Lines changed: 378 additions & 170 deletions

File tree

.eslintrc.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,10 @@
1212
"parser": "@typescript-eslint/parser",
1313
"plugins": ["@typescript-eslint"],
1414

15-
"root": true
15+
"root": true,
16+
17+
"rules": {
18+
"no-unused-vars": "error",
19+
"@typescript-eslint/no-unused-vars": "off"
20+
}
1621
}

.github/workflows/ci.yml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,6 @@ jobs:
4141
- name: test
4242
run: yarn test
4343

44-
check-format:
45-
runs-on: ubuntu-latest
46-
name: Check format 🔍
47-
steps:
48-
- uses: actions/checkout@v2
49-
50-
- name: install dependencies
51-
run: yarn install
52-
53-
- name: check format
54-
run: yarn format:check
55-
5644
lint:
5745
runs-on: ubuntu-latest
5846
name: Lint ✔

__mocks__/obsidian.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { parse } from "yaml";
22

3+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
34
export function parseYaml(text: string): any {
45
return parse(text);
56
}

jest.config.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
const config = {
2-
verbose: true,
3-
transform: {
4-
"^.+\\.tsx?$": "ts-jest",
5-
},
1+
import type { JestConfigWithTsJest } from "ts-jest";
2+
3+
const jestConfig: JestConfigWithTsJest = {
4+
// [...]
5+
// Replace `ts-jest` with the preset you want to use
6+
// from the above list
7+
preset: "ts-jest/presets/js-with-babel-esm",
68
};
7-
export default config;
9+
10+
export default jestConfig;

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,27 @@
33
"version": "1.2.1",
44
"description": "A plugin for displaying mathematical functions in obsidian.md.",
55
"repository": "https://github.com/leonhma/obsidian-functionplot",
6+
"type": "module",
67
"author": "leonhma",
78
"license": "MIT",
89
"private": true,
910
"scripts": {
1011
"build": "webpack",
11-
"test": "jest",
12+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
1213
"format": "yarn prettier --write .",
13-
"format:check": "yarn prettier --check .",
1414
"lint": "yarn eslint ."
1515
},
1616
"devDependencies": {
1717
"@types/jest": "^29.2.0",
18+
"@types/node": "*",
1819
"@typescript-eslint/eslint-plugin": "^5.41.0",
1920
"@typescript-eslint/parser": "^5.41.0",
21+
"cjstoesm": "^2.1.2",
22+
"default-import": "^1.1.5",
2023
"eslint": "^8.26.0",
2124
"eslint-config-prettier": "^8.5.0",
2225
"jest": "^29.2.2",
26+
"jest-environment-node": "^29.2.2",
2327
"prettier": "^2.7.1",
2428
"sass": "^1.54.4",
2529
"sass-loader": "^13.0.2",
@@ -33,6 +37,7 @@
3337
},
3438
"dependencies": {
3539
"function-plot": "^1.22.9-0",
40+
"html-to-image": "^1.10.8",
3641
"obsidian": "0.12.2"
3742
}
3843
}

src/app/CreatePlotModal.ts

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
import { Chart } from "function-plot";
22
import { FunctionPlotDatum } from "function-plot/dist/types";
3-
import { App, Modal, Setting } from "obsidian";
4-
import { DEFAULT_PLOT_OPTIONS, PlotOptions } from "../types";
3+
import { Editor, Modal, Setting } from "obsidian";
4+
import { DEFAULT_PLOT_OPTIONS, rendererOptions } from "../common/defaults";
5+
import { PlotOptions, rendererType } from "../common/types";
56
import ObsidianFunctionPlot, { createPlot } from "../main";
7+
import { renderPlotAsImage, renderPlotAsInteractive } from "../common/utils";
68

79
export default class CreatePlotModal extends Modal {
810
options: PlotOptions;
911
plugin: ObsidianFunctionPlot;
12+
editor: Editor;
1013
plot: Chart;
14+
renderer: rendererType;
1115

12-
onSubmit: (result: PlotOptions) => void;
13-
14-
constructor(
15-
app: App,
16-
plugin: ObsidianFunctionPlot,
17-
onSubmit: (result: PlotOptions) => void
18-
) {
19-
super(app);
16+
constructor(plugin: ObsidianFunctionPlot, editor: Editor) {
17+
super(plugin.app);
2018
this.plugin = plugin;
21-
this.onSubmit = onSubmit;
19+
this.editor = editor;
20+
this.renderer = this.plugin.settings.defaultRenderer;
2221
}
2322

24-
// skipcq: JS-0376
23+
/**
24+
* Reload the preview using internal functions. Zooming doesn't work here.
25+
* @returns A Promise
26+
*/
2527
async reloadPreview() {
2628
if (!this.plot) return;
2729
// update values
@@ -96,10 +98,10 @@ export default class CreatePlotModal extends Modal {
9698

9799
new Setting(settings)
98100
.setName("Bounds")
99-
.setDesc("Bounds must be written in this format: minX, maxX, minY, maxY")
101+
.setDesc("Bounds must be written in this format: minX, maxX, minY, maxY.")
100102
.addText((text) => {
101103
text.setPlaceholder(DEFAULT_PLOT_OPTIONS.bounds.join(", "));
102-
text.onChange(async (_) => {
104+
text.onChange(async () => {
103105
let bounds = text
104106
.getValue()
105107
.split(",")
@@ -134,7 +136,7 @@ export default class CreatePlotModal extends Modal {
134136
new Setting(settings)
135137
.setName("Functions")
136138
.setDesc(
137-
"Specify functions to plot. Must be in format: <name>(x) = <expression>"
139+
"Specify functions to plot. Must be in format: <name>(x) = <expression>."
138140
)
139141
.addTextArea((com) => {
140142
com.onChange(async (value) => {
@@ -147,26 +149,39 @@ export default class CreatePlotModal extends Modal {
147149
});
148150
});
149151

150-
new Setting(contentEl).addButton((btn) => {
151-
btn
152-
.setButtonText("Plot")
153-
.setCta()
154-
.onClick(() => {
155-
this.close();
156-
this.onSubmit({
157-
title: this.options.title,
158-
xLabel: this.options.xLabel,
159-
yLabel: this.options.yLabel,
160-
bounds: this.options.bounds,
161-
disableZoom: this.options.disableZoom,
162-
grid: this.options.grid,
163-
functions: this.options.functions,
152+
new Setting(contentEl)
153+
.addDropdown((com) => {
154+
com
155+
.addOptions(rendererOptions)
156+
.setValue(this.plugin.settings.defaultRenderer)
157+
.onChange((value: rendererType) => {
158+
this.renderer = value;
164159
});
165-
});
166-
});
160+
})
161+
.addButton((btn) => {
162+
btn
163+
.setButtonText("Plot")
164+
.setCta()
165+
.onClick(async () => {
166+
await this.handlePlotCreate(this.options);
167+
});
168+
});
169+
}
170+
171+
async handlePlotCreate(options: PlotOptions) {
172+
// render and insert chosen plot using renderer
173+
switch (this.renderer) {
174+
case "interactive":
175+
await renderPlotAsInteractive(this.plugin, this.editor, options);
176+
break;
177+
case "image":
178+
await renderPlotAsImage(this.plugin, this.editor, options);
179+
break;
180+
}
181+
182+
this.close();
167183
}
168184

169-
// skipcq: JS-0376
170185
async onClose() {
171186
const { contentEl } = this;
172187
contentEl.empty();

src/app/SettingsTab.ts

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import {
55
Setting,
66
ValueComponent,
77
} from "obsidian";
8-
import ObsidianFunctionPlot from "../main";
9-
import { DEFAULT_PLOT_PLUGIN_SETTINGS } from "../types";
8+
import ObsidianFunctionPlot from "../main.js";
9+
import { DEFAULT_PLUGIN_SETTINGS, rendererOptions } from "../common/defaults";
10+
import { PluginSettings, rendererType } from "../common/types";
1011

1112
export default class SettingsTab extends PluginSettingTab {
1213
plugin: ObsidianFunctionPlot;
13-
settingsInputs: Map<string, ValueComponent<string | number>>;
14+
settingsInputs: Map<keyof PluginSettings, ValueComponent<unknown>>;
1415

1516
constructor(app: App, plugin: ObsidianFunctionPlot) {
1617
super(app, plugin);
@@ -23,6 +24,31 @@ export default class SettingsTab extends PluginSettingTab {
2324
containerEl.empty();
2425

2526
containerEl.createEl("h1", { text: "Settings" });
27+
28+
/*
29+
* Default Plot Options
30+
*/
31+
32+
containerEl.createEl("h3", { text: "Default Plot Options" });
33+
34+
new Setting(containerEl)
35+
.setName("Default Render Type")
36+
.setDesc("The default renderer to use.")
37+
.addDropdown((com) => {
38+
this.settingsInputs.set("defaultRenderer", com);
39+
com
40+
.addOptions(rendererOptions)
41+
.setValue(this.plugin.settings.defaultRenderer)
42+
.onChange(async (value: rendererType) => {
43+
this.plugin.settings.defaultRenderer = value;
44+
await this.plugin.saveSettings();
45+
});
46+
});
47+
48+
/*
49+
* Font Sizes
50+
*/
51+
2652
containerEl.createEl("h3", { text: "Font Sizes" });
2753

2854
new Setting(containerEl)
@@ -70,6 +96,10 @@ export default class SettingsTab extends PluginSettingTab {
7096
.setDynamicTooltip();
7197
});
7298

99+
/*
100+
* Line Widths
101+
*/
102+
73103
containerEl.createEl("h3", { text: "Line Widths" });
74104

75105
new Setting(containerEl)
@@ -102,6 +132,10 @@ export default class SettingsTab extends PluginSettingTab {
102132
.setDynamicTooltip();
103133
});
104134

135+
/*
136+
* Colors
137+
*/
138+
105139
containerEl.createEl("h3", {
106140
attr: { style: "margin-bottom: 0" },
107141
text: "Colors",
@@ -115,7 +149,7 @@ export default class SettingsTab extends PluginSettingTab {
115149

116150
new Setting(containerEl)
117151
.setName("Font Color")
118-
.setDesc("Color used for the title and labels. ")
152+
.setDesc("Color used for the title and labels.")
119153
.addText((text) => {
120154
this.settingsInputs.set("fontColor", text);
121155
text
@@ -128,7 +162,7 @@ export default class SettingsTab extends PluginSettingTab {
128162

129163
new Setting(containerEl)
130164
.setName("Line Color")
131-
.setDesc("Color used for the domain- and origin-lines. ")
165+
.setDesc("Color used for the domain- and origin-lines.")
132166
.addText((text) => {
133167
this.settingsInputs.set("lineColor", text);
134168
text
@@ -141,7 +175,7 @@ export default class SettingsTab extends PluginSettingTab {
141175

142176
new Setting(containerEl)
143177
.setName("Grid Color")
144-
.setDesc("Color used for the gridlines. ")
178+
.setDesc("Color used for the gridlines.")
145179
.addText((text) => {
146180
this.settingsInputs.set("gridColor", text);
147181
text
@@ -152,27 +186,23 @@ export default class SettingsTab extends PluginSettingTab {
152186
});
153187
});
154188

155-
new Setting(containerEl)
156-
.addButton((btn) => {
157-
btn
158-
.setButtonText("Reset Settings to Default")
159-
.setWarning()
160-
.onClick((_) => {
161-
Object.assign(this.plugin.settings, DEFAULT_PLOT_PLUGIN_SETTINGS);
162-
this.settingsInputs.forEach((input, key) => {
163-
input.setValue(this.plugin.settings[key]);
164-
});
165-
this.plugin.saveSettings();
166-
new Notice("Obsidian Functionplot: Settings reset to default.");
167-
});
168-
})
169-
.addButton((btn) => {
170-
btn
171-
.setButtonText("Save")
172-
.setCta()
173-
.onClick((_) => {
174-
new Notice("Obsidian Functionplot: Settings saved.");
175-
});
176-
});
189+
/*
190+
* Reset Settings
191+
*/
192+
193+
new Setting(containerEl).addButton((btn) => {
194+
btn
195+
.setButtonText("Reset Settings to Default")
196+
.setWarning()
197+
.onClick(() => {
198+
Object.assign(this.plugin.settings, DEFAULT_PLUGIN_SETTINGS);
199+
for (const [key, input] of this.settingsInputs) {
200+
if (key === "telemetry") continue; // don't reset telemetry
201+
input.setValue(this.plugin.settings[key]);
202+
}
203+
this.plugin.saveSettings();
204+
new Notice("Settings reset to default");
205+
});
206+
});
177207
}
178208
}

0 commit comments

Comments
 (0)