Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
972b6c9
converted reactWebviewPanelController tests
Benjin Sep 24, 2025
f026f68
converted userSurvey tests
Benjin Sep 26, 2025
bd20997
test: replace TypeMoq with Sinon in azureResourceService tests
Benjin Sep 26, 2025
7697f8b
converted azureResourceService.test.ts
Benjin Sep 29, 2025
7620780
converted queryNotificationHandler.test.ts
Benjin Sep 29, 2025
bf57343
converted confirm.test.ts
Benjin Sep 29, 2025
dbfa8f6
Converted prompts.test.ts
Benjin Sep 29, 2025
db0f6b1
converting mssqlProtocolHandler.test.ts
Benjin Sep 30, 2025
a7a1de1
converted server.test.ts
Benjin Sep 30, 2025
6a13f03
converted scriptingService.test.ts
Benjin Sep 30, 2025
2232901
converted extConfig.test.ts
Benjin Sep 30, 2025
e6e8c25
converted executionPlanWebviewController.test.ts
Benjin Sep 30, 2025
c1f3236
converted metadataService.test.ts
Benjin Sep 30, 2025
ea97400
converted list.test.ts
Benjin Sep 30, 2025
d22bb94
converted adapter.test.ts
Benjin Sep 30, 2025
81d20d3
converted firewallService.test.ts
Benjin Sep 30, 2025
09ee2c4
converted databaseObjectSearchService.test.ts
Benjin Sep 30, 2025
7edbfa6
cleaned up some tests
Benjin Sep 30, 2025
4886de7
cleaned up list.test.ts
Benjin Sep 30, 2025
1be9d3f
fixed up adapter.test.ts
Benjin Sep 30, 2025
ac5488d
cleaned up firewallService.test.ts
Benjin Sep 30, 2025
9b130ae
added test/unit AGENTS.md
Benjin Sep 30, 2025
ae4e969
Adding AGENTS.md for unit test folder
Benjin Oct 2, 2025
45b3d97
Merge branch 'dev/benjin/convertUnitTestsLongRun' into dev/benjin/age…
Benjin Oct 2, 2025
183831d
converted tableDesigner.test.ts
Benjin Oct 2, 2025
ba44ccd
swapping to correct assertions
Benjin Oct 2, 2025
58e80b4
Merge branch 'main' into dev/benjin/convertTypeMoqTests
Benjin Oct 2, 2025
9963e3f
reverting AGENTS and README
Benjin Oct 3, 2025
bf7ee0c
fixing import for test
Benjin Oct 3, 2025
ed7a4c0
Merge branch 'main' into dev/benjin/convertTypeMoqTests
Benjin Oct 3, 2025
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
51 changes: 4 additions & 47 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
# MSSQL Extension for Visual Studio Code

The MSSQL Extension for Visual Studio Code is a TypeScript-based VS Code extension that provides database management capabilities for SQL Server, Azure SQL, and SQL Database in Fabric. The extension includes React-based webview components, AI-powered features with GitHub Copilot integration, and comprehensive SQL development tools.

**Always reference these instructions first** and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.

## Working Effectively

### Bootstrap, Build, and Test the Repository

**NEVER CANCEL** any build or test commands. These operations can take significant time and should be allowed to complete.

#### Initial Setup (Required once)
Expand All @@ -26,11 +16,6 @@ yarn install
```bash
# Full build - takes ~19 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
yarn build

# Development watch mode (for active development)
yarn watch
# This runs continuous compilation and bundling. Leave running during development.
# Includes: extension TypeScript, webview React/TypeScript, and asset bundling.
```

#### Individual Build Steps (if needed)
Expand All @@ -43,39 +28,21 @@ yarn build:prepare
yarn build:extension

# Bundle extension (~1 second)
yarn build:extension-bundle

# Compile React webviews (~8 seconds)
yarn build:webviews

# Bundle webviews (~2 seconds)
yarn build:webviews-bundle
```

### Linting and Code Quality

```bash
````bash
# Lint source files only - takes ~1.5 seconds
yarn lint src/ test/

# DO NOT run 'yarn lint' without arguments - it will fail trying to lint build output
```

### Testing

#### Unit Tests

```bash
# Unit tests require VS Code download and cannot run in sandboxed environments
# This is expected behavior - tests work in CI with proper VS Code setup
yarn test
# Expected to fail with "ENOTFOUND update.code.visualstudio.com" in sandboxed environments

# Run targeted unit tests using grep patterns
yarn test --grep "ConnectionManager" # Run tests matching "ConnectionManager"
yarn test --pattern ".*service.*" # Run tests matching service pattern
yarn test --testPattern "QueryRunner" # Alternative syntax for test filtering
```
````

#### E2E Tests (Smoke Tests)

Expand All @@ -87,17 +54,9 @@ yarn smoketest

### Packaging

```bash
````bash
# Install vsce globally (if not already installed)
npm install -g vsce

# Package extension - takes ~4.5 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
yarn package --online # Creates ~12MB VSIX file for online distribution
yarn package --offline # Creates platform-specific packages with embedded services
```

## Validation Scenarios

**Always test the following scenarios after making changes:**

### Complete Build Validation
Expand All @@ -120,9 +79,7 @@ yarn package --offline # Creates platform-specific packages with embedded servi
```bash
# Always run these commands before committing changes:
yarn build # Ensure code compiles
yarn lint src/ test/ # Ensure code meets style standards
yarn package --online # Ensure extension can be packaged
```
````

### Code Quality Validation

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ The following Visual Studio Code settings are available for the mssql extension.
// Status bar
{
"mssql.statusBar.connectionInfoMaxLength": -1,
"mssql.statusBar.enableConnectionColor": true,
"mssql.enableConnectionColor": true,
}
```

Expand Down
32 changes: 20 additions & 12 deletions media/changePassword_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 20 additions & 12 deletions media/changePassword_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 14 additions & 14 deletions src/reactviews/pages/ChangePassword/changePasswordSelector.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ChangePasswordWebviewState } from "../../../sharedInterfaces/changePassword";
import { useVscodeSelector } from "../../common/useVscodeSelector";
export function useChangePasswordSelector<T>(
selector: (state: ChangePasswordWebviewState) => T,
equals?: (a: T, b: T) => boolean,
) {
return useVscodeSelector<ChangePasswordWebviewState, void, T>(selector, equals);
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ChangePasswordWebviewState } from "../../../sharedInterfaces/changePassword";
import { useVscodeSelector } from "../../common/useVscodeSelector";

export function useChangePasswordSelector<T>(
selector: (state: ChangePasswordWebviewState) => T,
equals?: (a: T, b: T) => boolean,
) {
return useVscodeSelector<ChangePasswordWebviewState, void, T>(selector, equals);
}
61 changes: 36 additions & 25 deletions test/unit/adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as vscode from "vscode";
import * as TypeMoq from "typemoq";
import { expect } from "chai";
import * as chai from "chai";
import sinonChai from "sinon-chai";
import * as sinon from "sinon";
import CodeAdapter from "../../src/prompts/adapter";
import VscodeWrapper from "../../src/controllers/vscodeWrapper";
import { IQuestion } from "../../src/prompts/question";
import { stubVscodeWrapper } from "./utils";

chai.use(sinonChai);

suite("Code Adapter Tests", () => {
let sandbox: sinon.SinonSandbox;
let adapter: CodeAdapter;
let outputChannel: TypeMoq.IMock<vscode.OutputChannel>;
let vscodeWrapper: TypeMoq.IMock<VscodeWrapper>;
let mockVscodeWrapper: sinon.SinonStubbedInstance<VscodeWrapper>;

const testMessage = {
message: "test_message",
code: 123,
Expand All @@ -27,53 +33,58 @@ suite("Code Adapter Tests", () => {
};

setup(() => {
vscodeWrapper = TypeMoq.Mock.ofType(VscodeWrapper, TypeMoq.MockBehavior.Loose);
outputChannel = TypeMoq.Mock.ofType<vscode.OutputChannel>();
outputChannel.setup((o) => o.appendLine(TypeMoq.It.isAnyString()));
outputChannel.setup((o) => o.clear());
outputChannel.setup((o) => o.show());
vscodeWrapper.setup((v) => v.outputChannel).returns(() => outputChannel.object);
vscodeWrapper.setup((v) => v.showErrorMessage(TypeMoq.It.isAnyString()));
adapter = new CodeAdapter(vscodeWrapper.object);
sandbox = sinon.createSandbox();
mockVscodeWrapper = stubVscodeWrapper(sandbox);

mockVscodeWrapper.showErrorMessage.resolves(undefined);

adapter = new CodeAdapter(mockVscodeWrapper);
});

teardown(() => {
sandbox.restore();
});

test("logError should append message to the channel", () => {
adapter.logError(testMessage);
outputChannel.verify((o) => o.appendLine(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
expect(mockVscodeWrapper.outputChannel.appendLine).to.have.been.calledOnce;
});

test("log should format message and append to the channel", () => {
adapter.log(testMessage);
outputChannel.verify((o) => o.appendLine(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
expect(mockVscodeWrapper.outputChannel.appendLine).to.have.been.calledOnce;
});

test("clearLog should clear from output channel", () => {
adapter.clearLog();
outputChannel.verify((o) => o.clear(), TypeMoq.Times.once());
expect(mockVscodeWrapper.outputChannel.clear).to.have.been.calledOnce;
});

test("showLog should show the output channel", () => {
adapter.showLog();
outputChannel.verify((o) => o.show(), TypeMoq.Times.once());
expect(mockVscodeWrapper.outputChannel.show).to.have.been.calledOnce;
});

test("promptSingle and promptCallback should call prompt", () => {
void adapter.promptSingle(testQuestion);
test("promptSingle and promptCallback should call prompt", async () => {
await adapter.promptSingle(testQuestion);
adapter.promptCallback([testQuestion], () => true);
// Error case
void adapter.prompt([{ type: "test", message: "test", name: "test" }]);
await adapter.prompt([{ type: "test", message: "test", name: "test" }]);
});

test("prompting a checkbox question should call fixQuestion", () => {
let formattedQuestion: IQuestion = {
test("prompting a checkbox question should call fixQuestion", async () => {
const formattedQuestion: IQuestion = {
type: "checkbox",
message: "test",
name: "test_checkbox",
choices: [{ name: "test_choice", value: "test_choice" }],
};
void adapter.promptSingle(formattedQuestion);
let question: any = Object.assign({}, formattedQuestion);
question.choices[0] = "test";
void adapter.promptSingle(question);
await adapter.promptSingle(formattedQuestion);
const question: IQuestion = {
...formattedQuestion,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
choices: ["test" as any], // Intentionally wrong type to trigger fixQuestion
};
await adapter.promptSingle(question);
});
});
Loading