8000 support test solution by jdneo · Pull Request #16 · LeetCode-OpenSource/vscode-leetcode · GitHub
[go: up one dir, main page]

Skip to content

support test solution #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ All notable changes to the "leetcode" extension will be documented in this file.

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

## [0.3.0]
### Added
- Test current solution file [(#15)](https://github.com/jdneo/vscode-leetcode/issues/15)

## [0.2.1]
### Fixed
- Fix the wrong icon bug in LeetCode Explorer [(#9)](https://github.com/jdneo/vscode-leetcode/issues/9)
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Solve LeetCode problems in VS Code.
- Switch and create session
- Show problems in explorer
- Search problems by keywords
- Test solutions by customized test case
- Submit solutions to LeetCode

### Sign In and Sign Out
Expand All @@ -32,6 +33,9 @@ Solve LeetCode problems in VS Code.
### Search Problems by Keywords
![SearchProblem](resources/gif/searchproblem.gif)

### Test solutions by customized test case
![TestSolution](resources/gif/testsolution.gif)

### Submit Solutions to LeetCode
![SubmitSolution](resources/gif/solveproblem.gif)

Expand All @@ -43,6 +47,7 @@ This extension provides several commands in the Command Palette (F1 or Ctrl + Sh
- **LeetCode: Create new session** - Create a new session
- **LeetCode: Refresh** - Refresh the LeetCode Explorer
- **LeetCode: Search Problem** - Search for problems by keywords
- **LeetCode: Test Current File** - Test the solution by customized test case
- **LeetCode: Submit** - Submit the solution to LeetCode

## Known Issues:
Expand All @@ -68,6 +73,7 @@ This extension is based on [@skygragon](https://github.com/skygragon)'s [leetcod
- 切换及创建 session
- 在 Explorer 中展示题目
- 根据关键字搜索题目
- 用自定义测试用例测试答案
- 向 LeetCode 提交答案

### 登入及登出
Expand All @@ -82,6 +88,9 @@ This extension is based on [@skygragon](https://github.com/skygragon)'s [leetcod
### 根据关键字搜索题目
![SearchProblem](resources/gif/searchproblem.gif)

### 用自定义测试用例测试答案
![TestSolution](resources/gif/testsolution.gif)

### 向 LeetCode 提交答案
![SubmitSolution](resources/gif/solveproblem.gif)

Expand All @@ -93,6 +102,7 @@ This extension is based on [@skygragon](https://github.com/skygragon)'s [leetcod
- **LeetCode: Create new session** - 创建一个新的答题进度存档
- **LeetCode: Refresh** - 刷新左侧题目列表视图
- **LeetCode: Search Problem** - 根据关键字搜索题目
- **LeetCode: Test Current File** - 用自定义测试用例测试答案
- **LeetCode: Submit** - 提交答案到 LeetCode

## 已知问题
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vscode-leetcode",
"displayName": "LeetCode",
"description": "Solve LeetCode problems in VS Code",
"version": "0.2.1",
"version": "0.3.0",
"author": "Sheng Chen",
"publisher": "shengchen",
"icon": "resources/LeetCode.png",
Expand Down Expand Up @@ -32,6 +32,7 @@
"onCommand:leetcode.refreshExplorer",
"onCommand:leetcode.showProblem",
"onCommand:leetcode.searchProblem",
"onCommand:leetcode.testSolution",
"onCommand:leetcode.submitSolution",
"onView:leetCodeExplorer"
],
Expand Down Expand Up @@ -78,6 +79,11 @@
"category": "LeetCode",
"icon": "resources/search.png"
},
{
"command": "leetcode.testSolution",
"title": "Test Current File",
"category": "LeetCode"
},
{
"command": "leetcode.submitSolution",
"title": "Submit",
Expand Down
Binary file added resources/gif/testsolution.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/commands/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export async function listProblems(channel: vscode.OutputChannel): Promise<IProb
}
return problems.reverse();
} catch (error) {
await promptForOpenOutputChannel("Failed to list problems. Please open the output channel for details", DialogType.error, channel);
await promptForOpenOutputChannel("Failed to list problems. Please open the output channel for details.", DialogType.error, channel);
return [];
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/commands/session.ts
A3DB
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import * as vscode from "vscode";
import { leetCodeManager } from "../leetCodeManager";
import { IQuickItemEx, leetCodeBinaryPath } from "../shared";
import * as cp from "../utils/cpUtils";
import { executeCommand } from "../utils/cpUtils";
import { DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils";

export async function getSessionList(channel: vscode.OutputChannel): Promise<ISession[]> {
Expand All @@ -12,7 +12,7 @@ export async function getSessionList(channel: vscode.OutputChannel): Promise<ISe
promptForSignIn();
return [];
}
const result: string = await cp.executeCommand(channel, "node", [leetCodeBinaryPath, "session"]);
const result: string = await executeCommand(channel, "node", [leetCodeBinaryPath, "session"]);
const lines: string[] = result.split("\n");
const sessions: ISession[] = [];
const reg: RegExp = /(.?)\s*(\d+)\s+(.*)\s+(\d+ \(\s*\d+\.\d+ %\))\s+(\d+ \(\s*\d+\.\d+ %\))/;
Expand Down Expand Up @@ -41,11 +41,11 @@ export async function selectSession(channel: vscode.OutputChannel): Promise<void
return;
}
try {
await cp.executeCommand(channel, "node", [leetCodeBinaryPath, "session", "-e", choice.value]);
await executeCommand(channel, "node", [leetCodeBinaryPath, "session", "-e", choice.value]);
vscode.window.showInformationMessage(`Successfully switched to session '${choice.label}'.`);
await vscode.commands.executeCommand("leetcode.refreshExplorer");
} catch (error) {
await promptForOpenOutputChannel("Failed to switch session. Please open the output channel for details", DialogType.error, channel);
await promptForOpenOutputChannel("Failed to switch session. Please open the output channel for details.", DialogType.error, channel);
}
}

Expand All @@ -67,7 +67,7 @@ async function parseSessionsToPicks(channel: vscode.OutputChannel): Promise<Arra
});
resolve(picks);
} catch (error) {
return await promptForOpenOutputChannel("Failed to list sessions. Please open the output channel for details", DialogType.error, channel);
return await promptForOpenOutputChannel("Failed to list sessions. Please open the output channel for details.", DialogType.error, channel);
}
});
}
Expand All @@ -81,10 +81,10 @@ export async function createSession(channel: vscode.OutputChannel): Promise<void
return;
}
try {
await cp.executeCommand(channel, "node", [leetCodeBinaryPath, "session", "-c", session]);
await executeCommand(channel, "node", [leetCodeBinaryPath, "session", "-c", session]);
vscode.window.showInformationMessage("New session created, you can switch to it by clicking the status bar.");
} catch (error) {
await promptForOpenOutputChannel("Failed to create session. Please open the output channel for details", DialogType.error, channel);
await promptForOpenOutputChannel("Failed to create session. Please open the output channel for details.", DialogType.error, channel);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/commands/show.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ async function showProblemInternal(channel: vscode.OutputChannel, id: string): P
if (match && match.length >= 2) {
await vscode.window.showTextDocument(vscode.Uri.file(match[1].trim()), { preview: false });
} else {
throw new Error("Failed to fetch the problem information");
throw new Error("Failed to fetch the problem information.");
}

if (!defaultLanguage && leetCodeConfig.get<boolean>("showSetDefaultLanguageHint")) {
Expand All @@ -72,7 +72,7 @@ async function showProblemInternal(channel: vscode.OutputChannel, id: string): P
}
}
} catch (error) {
await promptForOpenOutputChannel("Failed to fetch the problem information. Please open the output channel for details", DialogType.error, channel);
await promptForOpenOutputChannel("Failed to fetch the problem information. Please open the output channel for details.", DialogType.error, channel);
}
}

Expand Down
12 changes: 3 additions & 9 deletions src/commands/submit.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
"use strict";

import * as fse from "fs-extra";
import * as os from "os";
import * as path from "path";
import * as vscode from "vscode";
import { leetCodeManager } from "../leetCodeManager";
import { leetCodeBinaryPath } from "../shared";
import { executeCommand } from "../utils/cpUtils";
import { DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils";
import { DialogType, promptForOpenOutputChannel, promptForSignIn, showResultFile } from "../utils/uiUtils";

export async function submitSolution(channel: vscode.OutputChannel): Promise<void> {
if (!leetCodeManager.getUser()) {
Expand All @@ -25,11 +22,8 @@ export async function submitSolution(channel: vscode.OutputChannel): Promise<voi
const filePath: string = textEditor.document.uri.fsPath;
try {
const result: string = await executeCommand(channel, "node", [leetCodeBinaryPath, "submit", filePath]);
const resultPath: string = path.join(os.homedir(), ".leetcode", "Result");
await fse.ensureFile(resultPath);
await fse.writeFile(resultPath, result);
await vscode.window.showTextDocument(vscode.Uri.file(resultPath));
await showResultFile(result);
} catch (error) {
await promptForOpenOutputChannel("Failed to submit the solution. Please open the output channel for details", DialogType.error, channel);
await promptForOpenOutputChannel("Failed to submit the solution. Please open the output channel for details.", DialogType.error, channel);
}
}
86 changes: 86 additions & 0 deletions src/commands/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"use strict";

import * as fse from "fs-extra";
import * as vscode from "vscode";
import { leetCodeManager } from "../leetCodeManager";
import 10000 { IQuickItemEx, leetCodeBinaryPath, UserStatus } from "../shared";
import { executeCommand } from "../utils/cpUtils";
import { DialogType, promptForOpenOutputChannel, showFileSelectDialog, showResultFile } from "../utils/uiUtils";

export async function testSolution(channel: vscode.OutputChannel): Promise<void> {
try {
if (leetCodeManager.getStatus() === UserStatus.SignedOut) {
return;
}

const activeText: vscode.TextEditor | undefined = vscode.window.activeTextEditor;
if (!activeText) {
vscode.window.showErrorMessage("Please open a LeetCode solution file first.");
return;
}

const filePath = activeText.document.uri.fsPath;
const picks: Array<IQuickItemEx<string>> = [];
picks.push(
{
label: "$(three-bars) Default test cases",
description: "",
detail: "Test with the default cases",
value: ":default",
},
{
label: "$(pencil) Write directly...",
description: "",
detail: "Write test cases in input box",
value: ":direct",
},
{
label: "$(file-text) Browse...",
description: "",
detail: "Test with the writen cases in file",
value: ":file",
},
);
const choice: IQuickItemEx<string> | undefined = await vscode.window.showQuickPick(picks);
if (!choice) {
return;
}

let result: string | undefined;
switch (choice.value) {
case ":default":
result = await executeCommand(channel, "node", [leetCodeBinaryPath, "test", filePath]);
break;
case ":direct":
const testString: string | undefined = await vscode.window.showInputBox({
prompt: "Enter the test cases.",
validateInput: (s: string) => s && s.trim() ? undefined : "Test case must not be empty.",
placeHolder: "Example: [1,2,3]\\n4",
ignoreFocusOut: true,
});
if (testString) {
result = await executeCommand(channel, "node", [leetCodeBinaryPath, "test", filePath, "-t", `"${testString.replace(/"/g, "")}"`]);
}
break;
case ":file":
const testFile: vscode.Uri[] | undefined = await showFileSelectDialog();
if (testFile && testFile.length) {
const input: string = await fse.readFile(testFile[0].fsPath, "utf-8");
if (input.trim()) {
result = await executeCommand(channel, "node", [leetCodeBinaryPath, "test", filePath, "-t", `"${input.replace(/"/g, "").replace(/\r?\n/g, "\\n")}"`]);
} else {
vscode.window.showErrorMessage("The selected test file must not be empty.");
}
}
break;
default:
break;
}
if (!result) {
return;
}
await showResultFile(result);
} catch (error) {
await promptForOpenOutputChannel("Failed to test the solution. Please open the output channel for details.", DialogType.error, channel);
}
}
2 changes: 2 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as vscode from "vscode";
import * as session from "./commands/session";
import * as show from "./commands/show";
import * as submit from "./commands/submit";
import * as test from "./commands/test";
import { LeetCodeNode, LeetCodeTreeDataProvider } from "./leetCodeExplorer";
import { leetCodeManager } from "./leetCodeManager";
import { leetCodeStatusBarItem } from "./leetCodeStatusBarItem";
Expand All @@ -26,6 +27,7 @@ export async function activate(context: vscode.ExtensionContext) {
vscode.commands.registerCommand("leetcode.showProblem", (node: LeetCodeNode) => show.showProblem(channel, node)),
vscode.commands.registerCommand("leetcode.searchProblem", () => show.searchProblem(channel)),
vscode.commands.registerCommand("leetcode.refreshExplorer", () => leetCodeTreeDataProvider.refresh()),
vscode.commands.registerCommand("leetcode.testSolution", () => test.testSolution(channel)),
vscode.commands.registerCommand("leetcode.submitSolution", () => submit.submitSolution(channel)),
);

Expand Down
22 changes: 22 additions & 0 deletions src/utils/uiUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"use strict";

import * as fse from "fs-extra";
import * as opn from "opn";
import * as os from "os";
import * as path from "path";
import * as vscode from "vscode";

export namespace DialogOptions {
Expand Down Expand Up @@ -51,6 +54,25 @@ export async function promptForSignIn(): Promise<void> {
}
}

export async function showFileSelectDialog(): Promise<vscode.Uri[] | undefined> {
const defaultUri: vscode.Uri | undefined = vscode.workspace.rootPath ? vscode.Uri.file(vscode.workspace.rootPath) : undefined;
const options: vscode.OpenDialogOptions = {
defaultUri,
canSelectFiles: true,
canSelectFolders: false,
canSelectMany: false,
openLabel: "Select",
};
return await vscode.window.showOpenDialog(options);
}

export async function showResultFile(result: string): Promise<void> {
const resultPath: string = path.join(os.homedir(), ".leetcode", "Result");
await fse.ensureFile(resultPath);
await fse.writeFile(resultPath, result);
await vscode.window.showTextDocument(vscode.Uri.file(resultPath));
}

export enum DialogType {
info = "info",
warning = "warning",
Expand Down
0