From a6e45140570d21ab30de86d9617bb64ba07df7d4 Mon Sep 17 00:00:00 2001 From: Heliozoa Date: Tue, 17 Dec 2024 10:25:58 +0200 Subject: [PATCH 1/3] Fix error display in test run view --- CHANGELOG.md | 5 +++++ CONTRIBUTING.md | 4 ++++ config.js | 2 +- package-lock.json | 4 ++-- package.json | 2 +- shared/lib.ts | 14 +++++++++++- src/api/tmc.ts | 14 ++++++------ src/commands/downloadOldSubmission.ts | 22 ++++++++++++++++--- src/errors.ts | 10 ++------- webview-ui/src/panels/ExerciseTests.svelte | 25 ++++++++++++++++------ webview-ui/src/panels/Welcome.svelte | 6 ++++++ 11 files changed, 80 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11c0663e..a8b956e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [3.1.0] - 2024-12-17 + +- Fixed downloading old submissions for C# exercises +- Bumped TMC-langs version to 0.37.0 + ## [3.0.6] - 2024-11-07 - Added a warning for a large number of open exercises diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 922a3f03..e21b8798 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,6 +65,10 @@ Automatic build task starts the first time that the extension is launched from V You can also build the extension by running `npm run webpack` or `npm run webpack:watch`. +## Updating dependencies + +The tmc-langs version can be updated by changing the `TMC_LANGS_RUST_VERSION` variable in `config.js`. + ## Testing The tests use a mock backend which needs to be initialised. Run `cd backend && npm run setup` to do so. The tests can be run with `npm run test`. If you get a `Connection error: TypeError`, make sure the backend is running. diff --git a/config.js b/config.js index f7b9059a..122569f9 100644 --- a/config.js +++ b/config.js @@ -3,7 +3,7 @@ const path = require("path"); -const TMC_LANGS_RUST_VERSION = "0.36.4"; +const TMC_LANGS_RUST_VERSION = "0.37.0"; const mockTmcLocalMooc = { __TMC_BACKEND_URL__: JSON.stringify("http://localhost:4001"), diff --git a/package-lock.json b/package-lock.json index 344f3cbf..9d8b8941 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "test-my-code", - "version": "3.0.6", + "version": "3.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "test-my-code", - "version": "3.0.6", + "version": "3.1.0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index fef50063..5e751734 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "test-my-code", "displayName": "TestMyCode", - "version": "3.0.6", + "version": "3.1.0", "description": "TestMyCode extension for Visual Studio Code", "categories": [ "Education", diff --git a/shared/lib.ts b/shared/lib.ts index 0c1a32b7..7401a5d5 100644 --- a/shared/lib.ts +++ b/shared/lib.ts @@ -213,7 +213,7 @@ export type ExtensionToWebview = | { type: "testError"; target: TargetPanel; - error: Error; + error: BaseError; } | { type: "pasteResult"; @@ -523,3 +523,15 @@ export type Broadcast = Omit, "target">; export function assertUnreachable(x: never): never { throw new Error(`Unreachable ${JSON.stringify(x, null, 2)}`); } + +/* + * ======== errors ======== + */ +export class BaseError extends Error { + public readonly name: string = "Base Error"; + public details: string; + constructor(message?: string, details?: string) { + super(message); + this.details = details ?? ""; + } +} diff --git a/src/api/tmc.ts b/src/api/tmc.ts index 8c9b4dc4..0157af62 100644 --- a/src/api/tmc.ts +++ b/src/api/tmc.ts @@ -44,6 +44,7 @@ import { import { Logger } from "../utilities/logger"; import { SubmissionFeedback } from "./types"; +import { BaseError } from "../shared/shared"; interface Options { apiCacheLifetime?: string; @@ -68,7 +69,7 @@ interface LangsProcessArgs { interface LangsProcessRunner { interrupt(): void; - result: Promise>; + result: Promise>; } interface ResponseCacheEntry { @@ -261,7 +262,7 @@ export default class TMC { exercisePath: string, pythonExecutablePath?: string, progressCallback?: (progressPct: number, message?: string) => void, - ): [Promise>, () => void] { + ): [Promise>, () => void] { const env: { [key: string]: string } = {}; if (pythonExecutablePath) { env.TMC_LANGS_PYTHON_EXEC = pythonExecutablePath; @@ -279,6 +280,7 @@ export default class TMC { .andThen((x) => this._checkLangsResponse(x, "test-result")) .map((x) => x.data["output-data"]), ); + return [postResult, interrupt]; } @@ -946,21 +948,21 @@ export default class TMC { private _checkLangsResponse( langsResponse: OutputData, outputDataKind: T, - ): Result { + ): Result { if (!dataMatchesKind(langsResponse, outputDataKind)) { Logger.error("Unexpected TMC-langs response.", langsResponse); - return Err(new Error("Unexpected TMC-langs response.")); + return Err(new BaseError("Unexpected TMC-langs response.")); } if (langsResponse.status === "crashed") { Logger.error("Langs process crashed.", langsResponse.message, langsResponse.data); - return Err(new RuntimeError("Langs process crashed.")); + return Err(new BaseError("Langs process crashed.")); } if (langsResponse.result !== "error") { return Ok(langsResponse); } if (langsResponse.data?.["output-data-kind"] !== "error") { Logger.error("Unexpected data in error response.", langsResponse); - return Err(new Error("Unexpected data in error response")); + return Err(new BaseError("Unexpected data in error response")); } // after this point, we know we have an error diff --git a/src/commands/downloadOldSubmission.ts b/src/commands/downloadOldSubmission.ts index 995ea2a2..fd429442 100644 --- a/src/commands/downloadOldSubmission.ts +++ b/src/commands/downloadOldSubmission.ts @@ -56,14 +56,30 @@ export async function downloadOldSubmission( return; } - const submitFirst = await dialog.confirmation( + const submitFirstSelection = await dialog.selectItem( "Do you want to save the current state of the exercise by submitting it to TMC Server?", + ["Submit to server", "submit"], + ["Discard current state", "discard"], ); - if (submitFirst === undefined) { + if (submitFirstSelection === undefined) { Logger.debug("Answer for submitting first not provided, returning early."); return; } + let submitFirst = submitFirstSelection === "submit"; + // if we're submitting first, nothing will be lost anyway so it's probably okay to not annoy the user with a double confirm + if (!submitFirst) { + const confirm = await dialog.selectItem( + "Are you sure?", + ["No, save the current exercise state", "submit"], + ["Yes, discard current state", "discard"], + ); + if (confirm === undefined) { + return; + } + submitFirst = confirm === "submit"; + } + const editor = vscode.window.activeTextEditor; const document = editor?.document.uri; @@ -78,6 +94,6 @@ export async function downloadOldSubmission( } if (editor && document) { - vscode.commands.executeCommand("vscode.open", document, editor.viewColumn); + await vscode.commands.executeCommand("workbench.action.files.revert", document); } } diff --git a/src/errors.ts b/src/errors.ts index fefff091..035c4c6b 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,11 +1,5 @@ -class BaseError extends Error { - public readonly name: string = "Base Error"; - public details: string; - constructor(message?: string, details?: string) { - super(message); - this.details = details ? details : ""; - } -} +import { BaseError } from "./shared/shared"; + export class ApiError extends BaseError { public readonly name = "API Error"; } diff --git a/webview-ui/src/panels/ExerciseTests.svelte b/webview-ui/src/panels/ExerciseTests.svelte index e1f9dec4..1a219997 100644 --- a/webview-ui/src/panels/ExerciseTests.svelte +++ b/webview-ui/src/panels/ExerciseTests.svelte @@ -1,6 +1,11 @@ -{#if !$tryingToRunTestsForExam} +{#if !$tryingToRunTestsForExam && !$testError} {#if $testResults === undefined}

{panel.exercise.name}: Running tests

{:else if $testResults.testResult.status === "PASSED"} @@ -170,6 +172,14 @@ {/if} {:else}

{panel.course.title}: {panel.exercise.name}

+ + {#if $testError} +

Error while trying to run tests

+ + {$testError.details} + + {/if} +
You can submit your answer with the button below.
@@ -198,4 +208,7 @@ margin-top: 1rem; margin-bottom: 1rem; } + code { + white-space: pre-wrap; + } diff --git a/webview-ui/src/panels/Welcome.svelte b/webview-ui/src/panels/Welcome.svelte index af38e91a..b0ce4be8 100644 --- a/webview-ui/src/panels/Welcome.svelte +++ b/webview-ui/src/panels/Welcome.svelte @@ -72,6 +72,12 @@
+

3.1.0 - 2024-12-17

+

Fixed downloading old submissions for C# exercises

+

+ There was an issue in tmc-langs that caused the extension to fail to detect the + project directory within a submission after downloading it. +

3.0.6 - 2024-11-07

Added a warning for a large number of open exercises

From 3bc9228c49b632dbd4b4fabb233f405963dd8f2c Mon Sep 17 00:00:00 2001 From: Heliozoa Date: Tue, 17 Dec 2024 10:27:02 +0200 Subject: [PATCH 2/3] Add to changelog --- CHANGELOG.md | 1 + webview-ui/src/panels/Welcome.svelte | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8b956e2..b4d90664 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [3.1.0] - 2024-12-17 - Fixed downloading old submissions for C# exercises +- Fixed error messages not displaying in some cases when running tests - Bumped TMC-langs version to 0.37.0 ## [3.0.6] - 2024-11-07 diff --git a/webview-ui/src/panels/Welcome.svelte b/webview-ui/src/panels/Welcome.svelte index b0ce4be8..834603d5 100644 --- a/webview-ui/src/panels/Welcome.svelte +++ b/webview-ui/src/panels/Welcome.svelte @@ -78,6 +78,11 @@ There was an issue in tmc-langs that caused the extension to fail to detect the project directory within a submission after downloading it.

+

Fixed error messages not displaying in some cases when running tests

+

+ Certain types of errors were not being displayed when they occurred while running + tests. +

3.0.6 - 2024-11-07

Added a warning for a large number of open exercises

From a36b0284a78ee9d33af196eb97873740b95407ab Mon Sep 17 00:00:00 2001 From: Heliozoa Date: Tue, 17 Dec 2024 10:28:12 +0200 Subject: [PATCH 3/3] Try multiple rootdirs --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 996da533..83969ab2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ ], "typeRoots": ["./types", "./node_modules/@types"], "sourceMap": true, - "rootDir": "src", + "rootDirs": ["src", "shared"], "strict": true /* enable all strict type-checking options */ /* Additional Checks */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */