Skip to content
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

fix: update test icons to account for bundling, fix apexDB location, and fix checkpoint issue #4686

Merged
merged 8 commits into from
Feb 18, 2023

Conversation

gbockus-sf
Copy link
Contributor

What does this PR do?

Primarily this PR addresses fixing accessing files in the resources directory for bundled vsixes.

  • Icons shows in the lwc and Apex Test views.
  • Setting up the apexDb

Secondarily there was a simple fix to how checkpoints are handled so I just did the update here.

What issues does this PR fix or reference?

@W-12545057@ #4534
@W-12545057@ #4673

Functionality Before

No icons would show up in the Test views.
checkpoints would be removed out of order in the checkpoints view.

Functionality After

We have icons.
Screenshot 2023-02-16 at 12 42 09 AM

checkpoints are correctly removed from the debug panel when toggle in a cls.
Screenshot 2023-02-16 at 12 44 40 AM

Notes:
To exercise the checkpoints functionality you can toggle a checkpoint via the SFDX: Toggle Checkpoint command in the CP or by creating a breakpoint and setting the expression to 'checkpoint'. Checkpoints can also be removed by clicking an active checkpoint (breakpoint).

@gbockus-sf gbockus-sf requested a review from a team as a code owner February 16, 2023 06:49
@gbockus-sf gbockus-sf requested a review from randi274 February 16, 2023 06:49
@@ -82,7 +82,7 @@
"vscode:bundle:debugger": "lerna run bundle:debugger",
"vscode:bundle:extension": "lerna run bundle:extension",
"vscode:package": "npm run vscode:bundle:debugger && npm run vscode:bundle:extension && lerna run vscode:package --concurrency 1 && npm run reformat",
"vsix:install": "find ./packages -name '*.vsix' -exec code --install-extension {} \\;",
"vsix:install": "find ./packages -name '*.vsix' -exec code-insiders --install-extension {} \\;",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I'm the only one using this for vsix testing figured I'd update instead of always editing it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm - maybe we could have two? vsix:install and vsix:install:insiders?

return vscode.Uri.joinPath(baseUri, relativePath);
}

export const extensionUris = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the spirit of always handing Uri's the same way created a common helper in utils to handle repeatable tasks. Think pathUtils but for Uris.

const relativePathToToolsFolder = path.join(
projectPaths.relativeStateFolder(),
TOOLS
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format 🤷

@@ -808,14 +808,14 @@ export async function processBreakpointChangedForCheckpoints(
for (const bp of breakpointsChangedEvent.removed) {
if (bp.condition && bp.condition!.toLowerCase().indexOf(CHECKPOINT) >= 0) {
await lock.acquire(CHECKPOINTS_LOCK_STRING, async () => {
const breakpointId = (bp as any)._id;
const breakpointId = bp.id;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was the fix for the breakpoints panel. I'm not sure when this changed in the vscode spec, but def calls to light not referencing private properties in 3rd party libs as a best practice.

@@ -209,7 +208,7 @@ describe('Verify checkpoint callback for vscode.debug.onDidChangeBreakpoints', (

// Verify that a single checkpoint has been added to the checkpoint service
const theNode = checkpointService.returnCheckpointNodeIfAlreadyExists(
breakpointId
breakpoint.id
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the id value is readonly so we were unable to manipulate the breakpoint Id as was done previously. I just updated to use the existing id and it worked

// eslint:disable-next-line:no-var-requires
const baseConfig = require('../../config/jest.base.config');

module.exports = Object.assign({}, baseConfig);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first jest test in vscode-apex package.


export const DEBUGGER_LINE_BREAKPOINTS = 'debugger/lineBreakpoints';
export const DEBUGGER_EXCEPTION_BREAKPOINTS = 'debugger/exceptionBreakpoints';

export const LIGHT_BLUE_BUTTON = path.join(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the issue with the icons was the code assumed a location of the source and found the resources directory from the current file location. That doesn't work with bundling b/c the source moves from this dir to the minified js file. I created a new class to handle it in a sane way instead of trying to hack it together as a constant value.

import * as vscode from 'vscode';
import { VSCODE_APEX_EXTENSION_NAME } from '../constants';

const setupDB = (): void => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just refactored this out of the file of the class that uses it to make it easier to unit test.

unlinkSync(dbPath);
}

try {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same story as the icons logic wise. This was assuming previously it's location in the file system to find the resources directory ala const systemDb = path.join(__dirname, '..', '..', 'resources', 'apex.db');
I updated it to use the extensionUri method to find the extension directory which works for both dev and published versions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid

DARK_RED_BUTTON = 'DARK_RED_BUTTON',
DARK_GREEN_BUTTON = 'DARK_GREEN_BUTTON',
DARK_ORANGE_BUTTON = 'DARK_ORANGE_BUTTON'
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So my goal here was to make using this icons in code a simple and type safe thing. Will break it down in the helper file.

* @param key A key from the {@link IconsEnum}
* @returns The Uri to the icon image.
*/
const getIconPath = (key: iconKey) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we needed a way to get iconPaths. My first approach here was to initialize with the extensionContext so I could get the extensionPath. That lead to some ugliness due to the file using this being initialized early in the activation flow. To avoid race condition games and have to store the extensionContext here I altered this to use the extensionUri to get the base extension location.

const baseExtensionPath = extensionUris.extensionUri(
VSCODE_APEX_EXTENSION_NAME
);
const iconUri = extensionUris.join(baseExtensionPath, ICONS[key]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then using that Uri and the relative path to the icon I join them and return that Uri to be used by the outline provider.

Note that the outlineProvider implements a vscode tree view so the iconPaths are typed to Uris or strings.

* Get the Uri for an icon located in the resources directory.
* @param key A key from the {@link IconsEnum}
* @returns The Uri to the icon image.
*/
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2023-02-16 at 1 02 26 AM

Note the param here is limited to the key values from the Icons const (which are also the keys for the IconsEnum).
This allows us to use this method safely always limiting the param to the available icons (or getting a compile error)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweeet

@@ -368,4 +359,11 @@ export class ApexTestNode extends TestNode {
public contextValue = 'apexTest';
}

export const testOutlineProvider = new ApexTestOutlineProvider(null);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this was leading to all kinds of sadness trying to both write the tests and ensure when this ApexTestOutputProvider was being constructed. I don't love the poor substitute for a singleton, but I would have had to majorly refactor the int tests if I altered how this property is referenced.

This seemed like the lesser of two evils path but I'm open to suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a solid solution to avoid the big refactor to me.

const extensionPath = path.join(__filename, '..', '..', '..', '..', '..');
const LIGHT_BLUE_BUTTON = path.join(
const extensionPath = extensionUris.extensionUri(VSCODE_LWC_EXTENSION_NAME);
const LIGHT_BLUE_BUTTON = extensionUris.join(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LWC constants were setup to be more easily updated so I went the easy path here instead of having two identical icon helpers.

true
);
expect(
groupNode.iconPath.dark.toString().endsWith('testNotRun.svg')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These updates are b/c the icon is now a Uri instead of a string path.

@klewis-sfdc
Copy link
Contributor

These code changes look great. Thanks for the update to make icons much more easy to work with!

I left a question re the script and a super small suggested fix. And it looks like the integration tests need to be tweaked but this looks really good.

@@ -280,20 +271,20 @@ export abstract class TestNode extends vscode.TreeItem {
if (outcome === 'Pass') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asking because you're in here anyway; is it worth extrapolating all the outcome strings into variables?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea..on it

gbockus-sf and others added 3 commits February 17, 2023 01:02
good catch

Co-authored-by: Ken Lewis <46458081+klewis-sfdc@users.noreply.github.com>
…rcedotcom/salesforcedx-vscode into gbockus/W-12545057-test-icons-missing
export const LSP_ERR = 'apexLSPError';

export const PASS_RESULT = 'Pass';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@@ -34,6 +31,9 @@ const NO_TESTS_DESCRIPTION = nls.localize(
'force_test_view_no_tests_description'
);

const TEST_RUN_ID_FILE = 'test-run-id.txt';
const TEST_RESULT_JSON_FILE = `test-result.json`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: ` vs ' here?

@randi274
Copy link
Contributor

QA:
✅ Colorful test indicators appear in both light and dark mode for Apex & LWC tests (confirmed blue, green, red, and orange)
✅ Checkpoints are now added/removed in a logical order, including when a breakpoint is converted
✅ Uploaded checkpoints and used replay debugger to make sure they were properly set
✅ Tested on both Mac and Windows

@@ -322,188 +322,6 @@ describe('Verify checkpoint callback for vscode.debug.onDidChangeBreakpoints', (
expect(lockSpy.getCall(1).args[0]).to.equal(CHECKPOINTS_LOCK_STRING);
});

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three tests depended on all checkpoints sharing the same _id property (undefined). I tried to see if I could use the real id property to get these tests to still work, but not luck (id is readonly). I also attempted to fake it but b/c there is an instanceof check in the code flow there was no getting around it. Elected to just remove these int tests vs continuing the fight or changing logic to accommodate the int tests.

@gbockus-sf gbockus-sf merged commit 3e50b48 into develop Feb 18, 2023
@gbockus-sf gbockus-sf deleted the gbockus/W-12545057-test-icons-missing branch February 18, 2023 04:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants