Visual modifications and fixes
This commit is contained in:
+28
-5
@@ -28,6 +28,12 @@ function isPalindrome(s) {
|
||||
}
|
||||
`;
|
||||
|
||||
const treeDataProvider = new MyTreeDataProvider();
|
||||
|
||||
const treeView = vscode.window.createTreeView("speedCodeResultTab", {
|
||||
treeDataProvider,
|
||||
});
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const statusBarItem = vscode.window.createStatusBarItem(
|
||||
vscode.StatusBarAlignment.Left,
|
||||
@@ -45,10 +51,6 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
timer: NodeJS.Timeout;
|
||||
};
|
||||
|
||||
const treeDataProvider = new MyTreeDataProvider();
|
||||
|
||||
vscode.window.registerTreeDataProvider("myCustomTab", treeDataProvider);
|
||||
|
||||
resetTimer = () => {
|
||||
if (run) {
|
||||
clearInterval(run.timer);
|
||||
@@ -58,6 +60,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
};
|
||||
|
||||
resetTimer();
|
||||
updateTreeMessage();
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("speed-code.submitSpeedRun", () => {
|
||||
@@ -84,6 +87,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
treeDataProvider.refresh();
|
||||
updateTreeMessage();
|
||||
} catch (e) {
|
||||
treeDataProvider.blunders.push([run.elapsed, String(e)]);
|
||||
}
|
||||
@@ -96,6 +100,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
treeDataProvider.testSummary = undefined;
|
||||
treeDataProvider.testResults = [];
|
||||
treeDataProvider.blunders = [];
|
||||
updateTreeMessage();
|
||||
const runFilePath = path.join(speedCodePath, "isPalindrome.js");
|
||||
fs.writeFileSync(runFilePath, "");
|
||||
openAndFocusFile(runFilePath);
|
||||
@@ -119,7 +124,13 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("speed-code.cancelSpeedRun", resetTimer),
|
||||
vscode.commands.registerCommand("speed-code.cancelSpeedRun", () => {
|
||||
resetTimer();
|
||||
treeDataProvider.testSummary = undefined;
|
||||
treeDataProvider.testResults = [];
|
||||
treeDataProvider.blunders = [];
|
||||
treeDataProvider.refresh();
|
||||
}),
|
||||
statusBarItem
|
||||
);
|
||||
}
|
||||
@@ -127,3 +138,15 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
export function deactivate() {
|
||||
resetTimer();
|
||||
}
|
||||
|
||||
function updateTreeMessage() {
|
||||
if (
|
||||
!treeDataProvider.testResults.length &&
|
||||
!treeDataProvider.blunders.length &&
|
||||
!treeDataProvider.testSummary
|
||||
) {
|
||||
treeView.message = "No results yet. Start a speedrun!";
|
||||
} else {
|
||||
treeView.message = "";
|
||||
}
|
||||
}
|
||||
|
||||
+47
-38
@@ -1,42 +1,51 @@
|
||||
import vm from 'vm';
|
||||
import assert from 'assert';
|
||||
import vm from "vm";
|
||||
import assert from "assert";
|
||||
|
||||
export interface TestCase { input: any[], expected: any };
|
||||
export interface TestResult extends TestCase { result: any, valid: boolean };
|
||||
|
||||
export default function testCode(code: string, testCases: TestCase[]): [boolean, TestResult[]] {
|
||||
const context: Record<string, any> = {};
|
||||
vm.createContext(context);
|
||||
|
||||
const beforeKeys = new Set(Object.keys(context));
|
||||
|
||||
const script = new vm.Script(code);
|
||||
script.runInContext(context);
|
||||
|
||||
const afterKeys = Object.keys(context);
|
||||
const newKeys = afterKeys.filter(k => !beforeKeys.has(k));
|
||||
|
||||
// Find the last function defined
|
||||
const funcs = newKeys
|
||||
.map(k => context[k])
|
||||
.filter(v => typeof v === 'function');
|
||||
|
||||
if (funcs.length === 0) {
|
||||
throw new Error("No function was defined in the code.");
|
||||
export interface TestCase {
|
||||
input: any[];
|
||||
expected: any;
|
||||
}
|
||||
export interface TestResult extends TestCase {
|
||||
result: any;
|
||||
valid: boolean;
|
||||
}
|
||||
|
||||
export default function testCode(
|
||||
code: string,
|
||||
testCases: TestCase[]
|
||||
): [boolean, TestResult[]] {
|
||||
const context: Record<string, any> = {};
|
||||
vm.createContext(context);
|
||||
|
||||
const beforeKeys = new Set(Object.keys(context));
|
||||
|
||||
const script = new vm.Script(code);
|
||||
script.runInContext(context);
|
||||
|
||||
const afterKeys = Object.keys(context);
|
||||
const newKeys = afterKeys.filter((k) => !beforeKeys.has(k));
|
||||
|
||||
// Find the last function defined
|
||||
const funcs = newKeys
|
||||
.map((k) => context[k])
|
||||
.filter((v) => typeof v === "function");
|
||||
|
||||
if (funcs.length === 0) {
|
||||
throw new Error("No function was defined in the code.");
|
||||
}
|
||||
|
||||
const targetFn = funcs[funcs.length - 1];
|
||||
|
||||
const tests = testCases.map((t) => {
|
||||
const result = targetFn(...t.input);
|
||||
|
||||
try {
|
||||
assert.strictEqual(result, t.expected);
|
||||
return { ...t, valid: true, result };
|
||||
} catch {
|
||||
return { ...t, valid: false, result };
|
||||
}
|
||||
|
||||
const targetFn = funcs[funcs.length - 1];
|
||||
|
||||
const tests = testCases.map((t) => {
|
||||
const result = targetFn(...t.input);
|
||||
|
||||
try {
|
||||
assert.strictEqual(result, t.expected);
|
||||
return { ...t, valid: true, result };
|
||||
} catch {
|
||||
return { ...t, valid: false, result };
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return [tests.every(t => t.valid), tests];
|
||||
return [tests.every((t) => t.valid), tests];
|
||||
}
|
||||
|
||||
+22
-16
@@ -1,17 +1,23 @@
|
||||
export function format(timeSeconds: number): string {
|
||||
if (timeSeconds > 86400) {
|
||||
const days = Math.floor(timeSeconds / 86400);
|
||||
const hours = Math.floor(timeSeconds / 3600);
|
||||
const minutes = Math.floor(timeSeconds / 60);
|
||||
return `${days}:${hours - (days * 24)}:${minutes - (hours * 60)}:${(timeSeconds - (minutes * 60)).toFixed(3)}`;
|
||||
} else if (timeSeconds >= 3600) {
|
||||
const hours = Math.floor(timeSeconds / 3600);
|
||||
const minutes = Math.floor(timeSeconds / 60);
|
||||
return `${hours}:${minutes - (hours * 60)}:${(timeSeconds - (minutes * 60)).toFixed(3)}`;
|
||||
} else if (timeSeconds >= 60) {
|
||||
const minutes = Math.floor(timeSeconds / 60);
|
||||
return `${minutes}:${(timeSeconds - (minutes * 60)).toFixed(3)}`;
|
||||
} else {
|
||||
return `${timeSeconds}`;
|
||||
}
|
||||
}
|
||||
if (timeSeconds > 86400) {
|
||||
const days = Math.floor(timeSeconds / 86400);
|
||||
const hours = Math.floor(timeSeconds / 3600);
|
||||
const minutes = Math.floor(timeSeconds / 60);
|
||||
return `${days}:${hours - days * 24}:${minutes - hours * 60}:${(
|
||||
timeSeconds -
|
||||
minutes * 60
|
||||
).toFixed(3)}`;
|
||||
} else if (timeSeconds >= 3600) {
|
||||
const hours = Math.floor(timeSeconds / 3600);
|
||||
const minutes = Math.floor(timeSeconds / 60);
|
||||
return `${hours}:${minutes - hours * 60}:${(
|
||||
timeSeconds -
|
||||
minutes * 60
|
||||
).toFixed(3)}`;
|
||||
} else if (timeSeconds >= 60) {
|
||||
const minutes = Math.floor(timeSeconds / 60);
|
||||
return `${minutes}:${(timeSeconds - minutes * 60).toFixed(3)}`;
|
||||
} else {
|
||||
return `${timeSeconds}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user