Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
ac61e6a
add testing guid md
kubrickcode Sep 15, 2025
5caa373
Modify the Markdown format work unit checkbox
kubrickcode Sep 15, 2025
1b4f326
refactor: extract validateShortcuts pure function from command-exec…
kubrickcode Sep 15, 2025
5b0b7a0
refactor: extract shortcut finder logic into pure function
kubrickcode Sep 15, 2025
e40dae2
refactor: extract command execution logic from createQuickPickWithSh…
kubrickcode Sep 15, 2025
1e87f44
refactor: extract pure functions from executeButtonCommand method
kubrickcode Sep 15, 2025
2384e78
code formatting
kubrickcode Sep 15, 2025
107c55a
refactor: extract QuickPick item creation logic from showGroupQuickPick
kubrickcode Sep 15, 2025
68f4193
refactor: extract recursive execution logic from executeAllCommands
kubrickcode Sep 15, 2025
6059416
feat: extract button priority calculation logic
kubrickcode Sep 15, 2025
c8199d3
refactor: extract tooltip text creation logic for testability
kubrickcode Sep 15, 2025
021794f
refactor: extract button command creation logic in status-bar-manager
kubrickcode Sep 15, 2025
0ccb536
refactor: extract refresh button configuration logic in status-bar-ma…
kubrickcode Sep 15, 2025
01adee6
refactor: extract tree item creation logic in CommandTreeProvider
kubrickcode Sep 15, 2025
1a5eb1a
refactor: extract createRootTreeItems function from getRootItems method
kubrickcode Sep 15, 2025
1a9f3f3
refactor(terminal-manager): extract pure functions for testability
kubrickcode Sep 15, 2025
bf5fee3
refactor(webview): extract HTML generation and config update logic
kubrickcode Sep 15, 2025
cf1249b
refactor(adapters): extract pure functions for better testability
kubrickcode Sep 15, 2025
73267e1
refactor: extract QuickPickItem creation logic in show-all-commands.ts
kubrickcode Sep 15, 2025
f1a7fe2
refactor(main): extract command registration logic to separate function
kubrickcode Sep 15, 2025
21d9af8
docs: Mark refactoring phase as completed in TESTING_GUIDE
kubrickcode Sep 15, 2025
7fc8fe0
testing setup
kubrickcode Sep 15, 2025
1184276
add test command in justfile
kubrickcode Sep 15, 2025
a4d4493
add vscode mock code
kubrickcode Sep 15, 2025
669a6c6
test: Add comprehensive tests for validateShortcuts function
kubrickcode Sep 15, 2025
f5593f5
test: add comprehensive tests for findShortcutItem function
kubrickcode Sep 15, 2025
9349333
test: add comprehensive tests for determineButtonExecutionType function
kubrickcode Sep 15, 2025
a44a707
test: add comprehensive tests for createQuickPickItems function
kubrickcode Sep 15, 2025
818701c
test: add unit tests for executeTerminalCommand function
kubrickcode Sep 15, 2025
c593e62
test: implement comprehensive tests for executeCommandsRecursively fu…
kubrickcode Sep 15, 2025
b10cfcf
test: add tests for calculateButtonPriority function
kubrickcode Sep 15, 2025
910a67d
test: add tests for createTooltipText function in status-bar-manager
kubrickcode Sep 15, 2025
bc3ef15
test: add comprehensive tests for createButtonCommand function
kubrickcode Sep 15, 2025
8e1f2b4
test: add comprehensive tests for configureRefreshButton function
kubrickcode Sep 15, 2025
b3e7b3f
test: add comprehensive tests for createTreeItemsFromGroup function
kubrickcode Sep 15, 2025
85e23d0
test: add unit tests for terminal-manager extracted functions
kubrickcode Sep 15, 2025
0eca48f
test: add tests for getButtonsFromConfig function
kubrickcode Sep 15, 2025
ca5a119
test: add tests for generateFallbackHtml function in webview-provider
kubrickcode Sep 15, 2025
2e36b6b
test(webview-provider): add comprehensive tests for replaceAssetPat…
kubrickcode Sep 15, 2025
1638323
test: add comprehensive tests for injectSecurityAndVSCodeApi function
kubrickcode Sep 15, 2025
e3bc739
test: add comprehensive tests for checkWebviewFilesExist function
kubrickcode Sep 15, 2025
347b1f6
test(webview-provider): add comprehensive tests for buildWebviewHtml …
kubrickcode Sep 15, 2025
5ec06bf
test: add updateButtonConfiguration tests and fix vscode mocking
kubrickcode Sep 15, 2025
f823f9c
test: add comprehensive tests for createQuickPickItemsFromButtons fun…
kubrickcode Sep 15, 2025
cdb1d39
test: complete test implementation for main.ts registerCommands function
kubrickcode Sep 15, 2025
fe4aabe
delete testing guide doc
kubrickcode Sep 15, 2025
ae18bf1
add test workflow
kubrickcode Sep 15, 2025
2a9c1f9
test cases covering:
kubrickcode Sep 15, 2025
93ee016
format code
kubrickcode Sep 15, 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
45 changes: 45 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Test

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [22.x]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "yarn"
cache-dependency-path: "src/extension/yarn.lock"

- name: Install just
run: |
wget -qO - 'https://proget.makedeb.org/debian-feeds/prebuilt-mpr.pub' | gpg --dearmor | sudo tee /usr/share/keyrings/prebuilt-mpr-archive-keyring.gpg 1> /dev/null
echo "deb [signed-by=/usr/share/keyrings/prebuilt-mpr-archive-keyring.gpg] https://proget.makedeb.org prebuilt-mpr $(lsb_release -cs)" | sudo tee /etc/apt/sources.list.d/prebuilt-mpr.list
sudo apt update
sudo apt install -y just

- name: Install dependencies
run: just deps

- name: Run tests with coverage
run: just test coverage

- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
directory: ./src/coverage/
fail_ci_if_error: false
11 changes: 11 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,14 @@ publish target="both":

run-view:
cd "{{ web_view_dir }}" && yarn dev

test mode="":
#!/usr/bin/env bash
cd "{{ extension_dir }}"
if [ "{{ mode }}" = "watch" ]; then
yarn test:watch
elif [ "{{ mode }}" = "coverage" ]; then
yarn test --coverage
else
yarn test
fi
39 changes: 39 additions & 0 deletions src/extension/__mocks__/vscode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Minimal VS Code mock for Jest testing
module.exports = {
TreeItem: class {
constructor(label, collapsibleState) {
this.label = label;
this.collapsibleState = collapsibleState;
}
},
TreeItemCollapsibleState: {
None: 0,
Collapsed: 1,
Expanded: 2,
},
ThemeIcon: class {
constructor(id) {
this.id = id;
}
},
Uri: {
file: jest.fn(),
},
window: {
showErrorMessage: jest.fn(),
showInformationMessage: jest.fn(),
createTreeView: jest.fn(),
},
commands: {
registerCommand: jest.fn(),
},
workspace: {
getConfiguration: jest.fn(),
onDidChangeConfiguration: jest.fn(),
},
ConfigurationTarget: {
Global: 1,
Workspace: 2,
WorkspaceFolder: 3,
},
};
20 changes: 20 additions & 0 deletions src/extension/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/** @type {import('jest').Config} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
roots: ["<rootDir>/src"],
testMatch: ["**/*.test.ts"],
transform: {
"^.+\\.ts$": "ts-jest",
},
collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts", "!src/**/*.test.ts"],
coverageDirectory: "coverage",
coverageReporters: ["text", "lcov", "html"],
moduleFileExtensions: ["ts", "js", "json"],
verbose: true,
clearMocks: true,
restoreMocks: true,
moduleNameMapper: {
"^vscode$": "<rootDir>/__mocks__/vscode.js",
},
};
14 changes: 11 additions & 3 deletions src/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,21 @@
"package": "vsce package --out versions/",
"install-package": "code --install-extension versions/quick-command-buttons-$npm_package_version.vsix",
"vsce-publish": "vsce publish",
"ovsx-publish": "ovsx publish"
"ovsx-publish": "ovsx publish",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:ci": "jest --ci --coverage --watchAll=false"
},
"devDependencies": {
"@jest/globals": "^30.1.2",
"@types/jest": "^30.0.0",
"@types/node": "24.3.0",
"@types/vscode": "^1.90.0",
"typescript": "5.9.2",
"@vscode/vsce": "3.0.0"
"@vscode/vsce": "3.0.0",
"jest": "^30.1.3",
"ts-jest": "^29.4.1",
"typescript": "5.9.2"
},
"dependencies": {}
}
52 changes: 52 additions & 0 deletions src/extension/src/adapters.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as vscode from "vscode";
import { createVSCodeConfigReader } from "./adapters";

describe("adapters", () => {
beforeEach(() => {
jest.clearAllMocks();
});

describe("getButtonsFromConfig", () => {
it("should return buttons from config", () => {
const mockButtons = [
{ name: "Test Button", command: "test command" },
{ name: "Another Button", command: "another command" },
];

const mockConfig = {
get: jest.fn((key: string) =>
key === "buttons" ? mockButtons : undefined
),
};

(vscode.workspace.getConfiguration as jest.Mock).mockReturnValue(
mockConfig
);

const configReader = createVSCodeConfigReader();
const result = configReader.getButtons();

expect(result).toEqual(mockButtons);
expect(vscode.workspace.getConfiguration).toHaveBeenCalledWith(
"quickCommandButtons"
);
expect(mockConfig.get).toHaveBeenCalledWith("buttons");
});

it("should return empty array when no buttons in config", () => {
const mockConfig = {
get: jest.fn(() => undefined),
};

(vscode.workspace.getConfiguration as jest.Mock).mockReturnValue(
mockConfig
);

const configReader = createVSCodeConfigReader();
const result = configReader.getButtons();

expect(result).toEqual([]);
expect(mockConfig.get).toHaveBeenCalledWith("buttons");
});
});
});
40 changes: 28 additions & 12 deletions src/extension/src/adapters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import * as vscode from "vscode";
import { ButtonConfig, RefreshButtonConfig } from "./types";

const CONFIG_SECTION = "quickCommandButtons";
const DEFAULT_REFRESH_CONFIG: RefreshButtonConfig = {
icon: "$(refresh)",
color: "#00BCD4",
enabled: true,
};

export type TerminalExecutor = (
command: string,
useVsCodeApi?: boolean,
Expand All @@ -22,21 +29,30 @@ export type QuickPickCreator = <
T extends vscode.QuickPickItem
>() => vscode.QuickPick<T>;

const getButtonsFromConfig = (
config: vscode.WorkspaceConfiguration
): ButtonConfig[] => config.get("buttons") || [];

const getRefreshConfigFromConfig = (
config: vscode.WorkspaceConfiguration
): RefreshButtonConfig => config.get("refreshButton") || DEFAULT_REFRESH_CONFIG;

const isQuickCommandButtonsConfigChange = (
event: vscode.ConfigurationChangeEvent
): boolean => event.affectsConfiguration(CONFIG_SECTION);

export const createVSCodeConfigReader = (): ConfigReader => ({
getButtons: () =>
vscode.workspace.getConfiguration("quickCommandButtons").get("buttons") ||
[],
getRefreshConfig: () =>
vscode.workspace
.getConfiguration("quickCommandButtons")
.get("refreshButton") || {
icon: "$(refresh)",
color: "#00BCD4",
enabled: true,
},
getButtons: () => {
const config = vscode.workspace.getConfiguration(CONFIG_SECTION);
return getButtonsFromConfig(config);
},
getRefreshConfig: () => {
const config = vscode.workspace.getConfiguration(CONFIG_SECTION);
return getRefreshConfigFromConfig(config);
},
onConfigChange: (listener: () => void) =>
vscode.workspace.onDidChangeConfiguration((event) => {
if (!event.affectsConfiguration("quickCommandButtons")) return;
if (!isQuickCommandButtonsConfigChange(event)) return;
listener();
}),
});
Expand Down
Loading