blunders
This commit is contained in:
+65
-37
@@ -1,12 +1,12 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from "vscode";
|
||||||
import os from 'os';
|
import os from "os";
|
||||||
import path from 'path';
|
import path from "path";
|
||||||
import fs from 'fs';
|
import fs from "fs";
|
||||||
import testCode, { TestResult } from './tester';
|
import testCode, { TestResult } from "./tester";
|
||||||
import * as utils from './utils';
|
import * as utils from "./utils";
|
||||||
import { MyTreeDataProvider } from './resultViewer';
|
import { MyTreeDataProvider } from "./resultViewer";
|
||||||
|
|
||||||
let resetTimer = () => {}
|
let resetTimer = () => {};
|
||||||
|
|
||||||
const speedCodePath = path.join(os.homedir(), ".speed-code/");
|
const speedCodePath = path.join(os.homedir(), ".speed-code/");
|
||||||
|
|
||||||
@@ -16,7 +16,10 @@ if (!fs.existsSync(speedCodePath)) {
|
|||||||
|
|
||||||
export async function openAndFocusFile(filePath: string) {
|
export async function openAndFocusFile(filePath: string) {
|
||||||
const document = await vscode.workspace.openTextDocument(filePath);
|
const document = await vscode.workspace.openTextDocument(filePath);
|
||||||
await vscode.window.showTextDocument(document, { preview: false, preserveFocus: false });
|
await vscode.window.showTextDocument(document, {
|
||||||
|
preview: false,
|
||||||
|
preserveFocus: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const userCode = `
|
const userCode = `
|
||||||
@@ -26,12 +29,25 @@ function isPalindrome(s) {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export function activate(context: vscode.ExtensionContext) {
|
export function activate(context: vscode.ExtensionContext) {
|
||||||
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100);
|
const statusBarItem = vscode.window.createStatusBarItem(
|
||||||
statusBarItem.tooltip = 'Speedrun timer';
|
vscode.StatusBarAlignment.Left,
|
||||||
|
100
|
||||||
|
);
|
||||||
|
statusBarItem.tooltip = "Speedrun timer";
|
||||||
statusBarItem.text = "No active Speedrun";
|
statusBarItem.text = "No active Speedrun";
|
||||||
statusBarItem.show();
|
statusBarItem.show();
|
||||||
|
|
||||||
let run: undefined | { path: string, elapsed: number, timer: NodeJS.Timeout, blunders: [number, TestResult[]][] };
|
let run:
|
||||||
|
| undefined
|
||||||
|
| {
|
||||||
|
path: string;
|
||||||
|
elapsed: number;
|
||||||
|
timer: NodeJS.Timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
const treeDataProvider = new MyTreeDataProvider();
|
||||||
|
|
||||||
|
vscode.window.registerTreeDataProvider("myCustomTab", treeDataProvider);
|
||||||
|
|
||||||
resetTimer = () => {
|
resetTimer = () => {
|
||||||
if (run) {
|
if (run) {
|
||||||
@@ -43,57 +59,69 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
|
|
||||||
resetTimer();
|
resetTimer();
|
||||||
|
|
||||||
const treeDataProvider = new MyTreeDataProvider();
|
context.subscriptions.push(
|
||||||
|
vscode.commands.registerCommand("speed-code.submitSpeedRun", () => {
|
||||||
vscode.window.registerTreeDataProvider('myCustomTab', treeDataProvider);
|
|
||||||
|
|
||||||
context.subscriptions.push(vscode.commands.registerCommand('speed-code.submitSpeedRun', () => {
|
|
||||||
if (run) {
|
if (run) {
|
||||||
try {
|
try {
|
||||||
const [isValid, res] = testCode(fs.readFileSync(run.path).toString(), [
|
const [isValid, res] = testCode(
|
||||||
|
fs.readFileSync(run.path).toString(),
|
||||||
|
[
|
||||||
{ input: ["racecar"], expected: true },
|
{ input: ["racecar"], expected: true },
|
||||||
{ input: ["hello"], expected: false },
|
{ input: ["hello"], expected: false },
|
||||||
{ input: ["madam"], expected: true },
|
{ input: ["madam"], expected: true },
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
treeDataProvider.testResults = res;
|
|
||||||
treeDataProvider.testSummary = { elapsed: run.elapsed, valid: isValid };
|
|
||||||
treeDataProvider.blunders = run.blunders;
|
|
||||||
treeDataProvider.refresh();
|
|
||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
|
treeDataProvider.testResults = res;
|
||||||
|
treeDataProvider.testSummary = {
|
||||||
|
elapsed: run.elapsed,
|
||||||
|
valid: isValid,
|
||||||
|
};
|
||||||
resetTimer();
|
resetTimer();
|
||||||
|
} else {
|
||||||
|
treeDataProvider.blunders.push([run.elapsed, res]);
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
// TODO: blunders
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
treeDataProvider.refresh();
|
||||||
|
} catch (e) {
|
||||||
|
treeDataProvider.blunders.push([run.elapsed, String(e)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
context.subscriptions.push(vscode.commands.registerCommand('speed-code.startSpeedRun', () => {
|
context.subscriptions.push(
|
||||||
const runFilePath = path.join(speedCodePath, 'isPalindrome.js');
|
vscode.commands.registerCommand("speed-code.startSpeedRun", () => {
|
||||||
fs.writeFileSync(runFilePath, '');
|
treeDataProvider.testSummary = undefined;
|
||||||
|
treeDataProvider.testResults = [];
|
||||||
|
treeDataProvider.blunders = [];
|
||||||
|
const runFilePath = path.join(speedCodePath, "isPalindrome.js");
|
||||||
|
fs.writeFileSync(runFilePath, "");
|
||||||
openAndFocusFile(runFilePath);
|
openAndFocusFile(runFilePath);
|
||||||
|
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
run = {
|
run = {
|
||||||
path: runFilePath,
|
path: runFilePath,
|
||||||
elapsed: 0,
|
elapsed: 0,
|
||||||
blunders: [],
|
|
||||||
timer: setInterval(() => {
|
timer: setInterval(() => {
|
||||||
if (!run) return;
|
if (!run) return;
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
run.elapsed = (currentTime - startTime) / 1000;
|
run.elapsed = (currentTime - startTime) / 1000;
|
||||||
statusBarItem.text = utils.format(run.elapsed);
|
statusBarItem.text = utils.format(run.elapsed);
|
||||||
statusBarItem.color = '#fff';
|
statusBarItem.color = "#fff";
|
||||||
}, 10),
|
}, 10),
|
||||||
};
|
};
|
||||||
|
|
||||||
vscode.window.showInformationMessage('Speedrun Started!');
|
vscode.window.showInformationMessage("Speedrun Started!");
|
||||||
}), statusBarItem);
|
}),
|
||||||
|
statusBarItem
|
||||||
|
);
|
||||||
|
|
||||||
context.subscriptions.push(vscode.commands.registerCommand('speed-code.cancelSpeedRun', resetTimer), statusBarItem);
|
context.subscriptions.push(
|
||||||
|
vscode.commands.registerCommand("speed-code.cancelSpeedRun", resetTimer),
|
||||||
|
statusBarItem
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deactivate() {
|
export function deactivate() {
|
||||||
|
|||||||
+78
-20
@@ -1,24 +1,41 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from "vscode";
|
||||||
import { TestResult } from './tester';
|
import { TestResult } from "./tester";
|
||||||
import { format } from './utils';
|
import { format } from "./utils";
|
||||||
|
|
||||||
class RunTreeItem extends vscode.TreeItem {
|
class RunTreeItem extends vscode.TreeItem {
|
||||||
children?: RunTreeItem[];
|
children?: RunTreeItem[];
|
||||||
|
|
||||||
constructor(label: string | vscode.TreeItemLabel, description?: string, children?: RunTreeItem[], expanded?: boolean) {
|
constructor(
|
||||||
super(label, children ? (expanded ? vscode.TreeItemCollapsibleState.Expanded : vscode.TreeItemCollapsibleState.Collapsed) : vscode.TreeItemCollapsibleState.None)
|
label: string | vscode.TreeItemLabel,
|
||||||
|
description?: string,
|
||||||
|
children?: RunTreeItem[],
|
||||||
|
expanded: boolean = false
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
label,
|
||||||
|
children
|
||||||
|
? expanded
|
||||||
|
? vscode.TreeItemCollapsibleState.Expanded
|
||||||
|
: vscode.TreeItemCollapsibleState.Collapsed
|
||||||
|
: vscode.TreeItemCollapsibleState.None
|
||||||
|
);
|
||||||
this.children = children;
|
this.children = children;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MyTreeDataProvider implements vscode.TreeDataProvider<RunTreeItem> {
|
export class MyTreeDataProvider
|
||||||
private _onDidChangeTreeData: vscode.EventEmitter<RunTreeItem | undefined | void> = new vscode.EventEmitter();
|
implements vscode.TreeDataProvider<RunTreeItem>
|
||||||
readonly onDidChangeTreeData: vscode.Event<RunTreeItem | undefined | void> = this._onDidChangeTreeData.event;
|
{
|
||||||
|
private _onDidChangeTreeData: vscode.EventEmitter<
|
||||||
|
RunTreeItem | undefined | void
|
||||||
|
> = new vscode.EventEmitter();
|
||||||
|
readonly onDidChangeTreeData: vscode.Event<RunTreeItem | undefined | void> =
|
||||||
|
this._onDidChangeTreeData.event;
|
||||||
|
|
||||||
testResults: TestResult[] = [];
|
testResults: TestResult[] = [];
|
||||||
testSummary: undefined | { elapsed: number, valid: boolean };
|
testSummary: undefined | { elapsed: number; valid: boolean };
|
||||||
blunders: [number, TestResult[]][] = [];
|
blunders: [number, string | TestResult[]][] = [];
|
||||||
|
|
||||||
refresh(): void {
|
refresh(): void {
|
||||||
this._onDidChangeTreeData.fire();
|
this._onDidChangeTreeData.fire();
|
||||||
@@ -33,20 +50,61 @@ export class MyTreeDataProvider implements vscode.TreeDataProvider<RunTreeItem>
|
|||||||
const items: RunTreeItem[] = [];
|
const items: RunTreeItem[] = [];
|
||||||
|
|
||||||
if (this.testSummary) {
|
if (this.testSummary) {
|
||||||
items.push(new RunTreeItem(`Speedrun Summary`, undefined, [
|
items.push(
|
||||||
|
new RunTreeItem(
|
||||||
|
`Speedrun Summary`,
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
new RunTreeItem("Time Elapsed", format(this.testSummary.elapsed)),
|
new RunTreeItem("Time Elapsed", format(this.testSummary.elapsed)),
|
||||||
new RunTreeItem("Test Passed", this.testSummary.valid ? '✅ Passed' : '❌ Failed'),
|
new RunTreeItem(
|
||||||
], true));
|
"Test Passed",
|
||||||
|
this.testSummary.valid ? "✅ Passed" : "❌ Failed"
|
||||||
|
),
|
||||||
|
new RunTreeItem("Blunders", `${this.blunders.length}`),
|
||||||
|
],
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: blunders
|
if (this.blunders.length > 0) {
|
||||||
|
items.push(
|
||||||
|
new RunTreeItem(
|
||||||
|
`Blunders`,
|
||||||
|
undefined,
|
||||||
|
this.blunders.map((blunder, i) =>
|
||||||
|
typeof blunder[1] === "string"
|
||||||
|
? new RunTreeItem(blunder[1], format(blunder[0]))
|
||||||
|
: new RunTreeItem(
|
||||||
|
`Output Blunder ${i + 1}`,
|
||||||
|
format(blunder[0]),
|
||||||
|
blunder[1].map(
|
||||||
|
(t) =>
|
||||||
|
new RunTreeItem(
|
||||||
|
`(${JSON.stringify(t.input)})`,
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
new RunTreeItem("Output", `${t.result}`),
|
||||||
|
new RunTreeItem("Expected Output", `${t.expected}`),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.testResults.forEach(t => {
|
this.testResults.forEach((t) => {
|
||||||
const item = new RunTreeItem(`(${JSON.stringify(t.input)})`, undefined, [
|
const item = new RunTreeItem(
|
||||||
new RunTreeItem('Output', `${t.result}`),
|
`(${JSON.stringify(t.input)})`,
|
||||||
new RunTreeItem('Expected Output', `${t.expected}`),
|
undefined,
|
||||||
]);
|
[
|
||||||
item.description = t.valid ? '✅ Passed' : '❌ Failed';
|
new RunTreeItem("Output", `${t.result}`),
|
||||||
|
new RunTreeItem("Expected Output", `${t.expected}`),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
item.description = t.valid ? "✅ Passed" : "❌ Failed";
|
||||||
items.push(item);
|
items.push(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user