Skip to content

Commit

Permalink
Add global configuration for justMyCode (#91)
Browse files Browse the repository at this point in the history
* Aff configuration

* Read just my code from settings too

* fix tests

* fix lint
  • Loading branch information
paulacamargo25 authored Sep 25, 2023
1 parent 5aaf0cc commit 81f79ed
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 80 deletions.
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@
}
]
},
"configuration": {
"properties": {
"debugpy.debugJustMyCode": {
"default": true,
"description": "%debugpy.debugJustMyCode%",
"scope": "resource",
"type": "boolean"
}
},
"title": "Python Debugger",
"type": "object"
},
"debuggers": [
{
"configurationAttributes": {
Expand Down
3 changes: 2 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"debugpy.command.debugInTerminal.title": "Debug Python File",
"debugpy.command.clearCacheAndReload.title": "Clear Cache and Reload Window",
"debugpy.command.viewOutput.title": "Show Output"
"debugpy.command.viewOutput.title": "Show Output",
"debugpy.debugJustMyCode": "When debugging only step through user-written code. Disable this to allow stepping into library code."
}
7 changes: 2 additions & 5 deletions src/extension/debugger/configuration/resolvers/attach.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CancellationToken, Uri, WorkspaceFolder } from 'vscode';
import { getOSType, OSType } from '../../../common/platform';
import { AttachRequestArguments, DebugOptions, PathMapping } from '../../../types';
import { BaseConfigurationResolver } from './base';
import { getConfiguration } from '../../../common/vscodeapi';

export class AttachConfigurationResolver extends BaseConfigurationResolver<AttachRequestArguments> {
public async resolveDebugConfigurationWithSubstitutedVariables(
Expand Down Expand Up @@ -42,16 +43,12 @@ export class AttachConfigurationResolver extends BaseConfigurationResolver<Attac
debugConfiguration.host = 'localhost';
}
if (debugConfiguration.justMyCode === undefined) {
// Populate justMyCode using debugStdLib
debugConfiguration.justMyCode = !debugConfiguration.debugStdLib;
debugConfiguration.justMyCode = getConfiguration('debugpy').get<boolean>('debugJustMyCode', true);
}
debugConfiguration.showReturnValue = debugConfiguration.showReturnValue !== false;
// Pass workspace folder so we can get this when we get debug events firing.
debugConfiguration.workspaceFolder = workspaceFolder ? workspaceFolder.fsPath : undefined;
const debugOptions = debugConfiguration.debugOptions!;
if (!debugConfiguration.justMyCode) {
AttachConfigurationResolver.debugOption(debugOptions, DebugOptions.DebugStdLib);
}
if (debugConfiguration.django) {
AttachConfigurationResolver.debugOption(debugOptions, DebugOptions.Django);
}
Expand Down
7 changes: 2 additions & 5 deletions src/extension/debugger/configuration/resolvers/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { DebugOptions, DebugPurpose, LaunchRequestArguments } from '../../../typ
import { resolveVariables } from '../utils/common';
import { BaseConfigurationResolver } from './base';
import { getDebugEnvironmentVariables, getProgram } from './helper';
import { getConfiguration } from '../../../common/vscodeapi';

export class LaunchConfigurationResolver extends BaseConfigurationResolver<LaunchRequestArguments> {
public async resolveDebugConfiguration(
Expand Down Expand Up @@ -102,15 +103,11 @@ export class LaunchConfigurationResolver extends BaseConfigurationResolver<Launc
debugConfiguration.debugOptions = [];
}
if (debugConfiguration.justMyCode === undefined) {
// Populate justMyCode using debugStdLib
debugConfiguration.justMyCode = !debugConfiguration.debugStdLib;
debugConfiguration.justMyCode = getConfiguration('debugpy').get<boolean>('debugJustMyCode', true);
}
// Pass workspace folder so we can get this when we get debug events firing.
debugConfiguration.workspaceFolder = workspaceFolder ? workspaceFolder.fsPath : undefined;
const debugOptions = debugConfiguration.debugOptions!;
if (!debugConfiguration.justMyCode) {
LaunchConfigurationResolver.debugOption(debugOptions, DebugOptions.DebugStdLib);
}
if (debugConfiguration.stopOnEntry) {
LaunchConfigurationResolver.debugOption(debugOptions, DebugOptions.StopOnEntry);
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/unittest/adapter/factory.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ suite('Debugging - Adapter Factory', () => {
assert.deepStrictEqual(descriptor, debugExecutable);
});

test.only('Display a message if no python interpreter is set', async () => {
test('Display a message if no python interpreter is set', async () => {
getActiveEnvironmentPathStub.resolves(undefined);
const session = createSession({});
const promise = factory.createDebugAdapterDescriptor(session, nodeExecutable);
Expand Down
70 changes: 37 additions & 33 deletions src/test/unittest/configuration/resolvers/attach.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
import { expect } from 'chai';
import * as TypeMoq from 'typemoq';
import * as sinon from 'sinon';
import { DebugConfiguration, DebugConfigurationProvider, TextDocument, TextEditor, Uri, WorkspaceFolder } from 'vscode';
import {
DebugConfiguration,
DebugConfigurationProvider,
TextDocument,
TextEditor,
Uri,
WorkspaceConfiguration,
WorkspaceFolder,
} from 'vscode';
import { PYTHON_LANGUAGE } from '../../../../extension/common/constants';
import { getInfoPerOS } from './common';
import { AttachRequestArguments, DebugOptions } from '../../../../extension/types';
Expand Down Expand Up @@ -34,6 +42,7 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
let getActiveTextEditorStub: sinon.SinonStub;
let getWorkspaceFoldersStub: sinon.SinonStub;
let getOSTypeStub: sinon.SinonStub;
let getConfigurationStub: sinon.SinonStub;
const debugOptionsAvailable = getAvailableOptions();

setup(() => {
Expand All @@ -42,6 +51,8 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
getOSTypeStub = sinon.stub(platform, 'getOSType');
getWorkspaceFoldersStub = sinon.stub(vscodeapi, 'getWorkspaceFolders');
getOSTypeStub.returns(osType);
getConfigurationStub = sinon.stub(vscodeapi, 'getConfiguration');
getConfigurationStub.withArgs('debugpy').returns(createMoqConfiguration(true));
});

teardown(() => {
Expand All @@ -54,6 +65,14 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
return folder.object;
}

function createMoqConfiguration(justMyCode: boolean) {
const debugpySettings = TypeMoq.Mock.ofType<WorkspaceConfiguration>();
debugpySettings
.setup((p) => p.get<boolean>('debugJustMyCode', TypeMoq.It.isAny()))
.returns(() => justMyCode);
return debugpySettings.object;
}

function setupActiveEditor(fileName: string | undefined, languageId: string) {
if (fileName) {
const textEditor = TypeMoq.Mock.ofType<TextEditor>();
Expand Down Expand Up @@ -493,67 +512,52 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
const testsForJustMyCode = [
{
justMyCode: false,
debugStdLib: true,
justMyCodeSetting: true,
expectedResult: false,
},
{
justMyCode: false,
debugStdLib: false,
justMyCodeSetting: false,
expectedResult: false,
},
{
justMyCode: false,
debugStdLib: undefined,
expectedResult: false,
},
{
justMyCode: true,
debugStdLib: false,
expectedResult: true,
},
{
justMyCode: true,
debugStdLib: true,
justMyCodeSetting: false,
expectedResult: true,
},
{
justMyCode: true,
debugStdLib: undefined,
expectedResult: true,
},
{
justMyCode: undefined,
debugStdLib: false,
justMyCodeSetting: true,
expectedResult: true,
},
{
justMyCode: undefined,
debugStdLib: true,
justMyCodeSetting: false,
expectedResult: false,
},
{
justMyCode: undefined,
debugStdLib: undefined,
justMyCodeSetting: true,
expectedResult: true,
},
];
test('Ensure justMyCode property is correctly derived from debugStdLib', async () => {
const activeFile = 'xyz.py';
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
setupActiveEditor(activeFile, PYTHON_LANGUAGE);
const defaultWorkspace = path.join('usr', 'desktop');
setupWorkspaces([defaultWorkspace]);
testsForJustMyCode.forEach(async (testParams) => {
test('Ensure justMyCode property is correctly derived from global settings', async () => {
const activeFile = 'xyz.py';
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
setupActiveEditor(activeFile, PYTHON_LANGUAGE);
const defaultWorkspace = path.join('usr', 'desktop');
setupWorkspaces([defaultWorkspace]);

const debugOptions = debugOptionsAvailable
.slice()
.concat(DebugOptions.Jinja, DebugOptions.Sudo) as DebugOptions[];
const debugOptions = debugOptionsAvailable
.slice()
.concat(DebugOptions.Jinja, DebugOptions.Sudo) as DebugOptions[];

testsForJustMyCode.forEach(async (testParams) => {
getConfigurationStub.withArgs('debugpy').returns(createMoqConfiguration(testParams.justMyCodeSetting));
const debugConfig = await resolveDebugConfiguration(workspaceFolder, {
...attach,
debugOptions,
justMyCode: testParams.justMyCode,
debugStdLib: testParams.debugStdLib,
});
expect(debugConfig).to.have.property('justMyCode', testParams.expectedResult);
});
Expand Down
71 changes: 36 additions & 35 deletions src/test/unittest/configuration/resolvers/launch.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
import { expect } from 'chai';
import * as TypeMoq from 'typemoq';
import * as sinon from 'sinon';
import { DebugConfiguration, DebugConfigurationProvider, TextDocument, TextEditor, Uri, WorkspaceFolder } from 'vscode';
import {
DebugConfiguration,
DebugConfigurationProvider,
TextDocument,
TextEditor,
Uri,
WorkspaceConfiguration,
WorkspaceFolder,
} from 'vscode';
import { PYTHON_LANGUAGE } from '../../../../extension/common/constants';
import { LaunchConfigurationResolver } from '../../../../extension/debugger/configuration/resolvers/launch';
import { getInfoPerOS } from './common';
Expand All @@ -31,6 +39,7 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
let getInterpreterDetailsStub: sinon.SinonStub;
let getEnvFileStub: sinon.SinonStub;
let getDebugEnvironmentVariablesStub: sinon.SinonStub;
let getConfigurationStub: sinon.SinonStub;

setup(() => {
getActiveTextEditorStub = sinon.stub(vscodeapi, 'getActiveTextEditor');
Expand All @@ -40,6 +49,8 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
getInterpreterDetailsStub = sinon.stub(pythonApi, 'getInterpreterDetails');
getEnvFileStub = sinon.stub(settings, 'getEnvFile');
getDebugEnvironmentVariablesStub = sinon.stub(helper, 'getDebugEnvironmentVariables');
getConfigurationStub = sinon.stub(vscodeapi, 'getConfiguration');
getConfigurationStub.withArgs('debugpy').returns(createMoqConfiguration(true));
});

teardown(() => {
Expand All @@ -52,6 +63,14 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
return folder.object;
}

function createMoqConfiguration(justMyCode: boolean) {
const debugpySettings = TypeMoq.Mock.ofType<WorkspaceConfiguration>();
debugpySettings
.setup((p) => p.get<boolean>('debugJustMyCode', TypeMoq.It.isAny()))
.returns(() => justMyCode);
return debugpySettings.object;
}

function getClientOS() {
return osType === platform.OSType.Windows ? 'windows' : 'unix';
}
Expand Down Expand Up @@ -726,11 +745,7 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
expect(debugConfig).to.have.property('redirectOutput', true);
expect(debugConfig).to.have.property('justMyCode', false);
expect(debugConfig).to.have.property('debugOptions');
const expectedOptions = [
DebugOptions.DebugStdLib,
DebugOptions.ShowReturnValue,
DebugOptions.RedirectOutput,
];
const expectedOptions = [DebugOptions.ShowReturnValue, DebugOptions.RedirectOutput];
if (osType === platform.OSType.Windows) {
expectedOptions.push(DebugOptions.FixFilePathCase);
}
Expand All @@ -740,60 +755,45 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
const testsForJustMyCode = [
{
justMyCode: false,
debugStdLib: true,
expectedResult: false,
},
{
justMyCode: false,
debugStdLib: false,
justMyCodeSetting: true,
expectedResult: false,
},
{
justMyCode: false,
debugStdLib: undefined,
justMyCodeSetting: false,
expectedResult: false,
},
{
justMyCode: true,
debugStdLib: false,
expectedResult: true,
},
{
justMyCode: true,
debugStdLib: true,
justMyCodeSetting: false,
expectedResult: true,
},
{
justMyCode: true,
debugStdLib: undefined,
justMyCodeSetting: true,
expectedResult: true,
},
{
justMyCode: undefined,
debugStdLib: false,
expectedResult: true,
},
{
justMyCode: undefined,
debugStdLib: true,
justMyCodeSetting: false,
expectedResult: false,
},
{
justMyCode: undefined,
debugStdLib: undefined,
justMyCodeSetting: true,
expectedResult: true,
},
];
test('Ensure justMyCode property is correctly derived from debugStdLib', async () => {
const pythonPath = `PythonPath_${new Date().toString()}`;
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
const pythonFile = 'xyz.py';
setupIoc(pythonPath);
setupActiveEditor(pythonFile, PYTHON_LANGUAGE);
testsForJustMyCode.forEach(async (testParams) => {
testsForJustMyCode.forEach(async (testParams) => {
test('Ensure justMyCode property is correctly derived from global settings', async () => {
const pythonPath = `PythonPath_${new Date().toString()}`;
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
const pythonFile = 'xyz.py';
setupIoc(pythonPath);
setupActiveEditor(pythonFile, PYTHON_LANGUAGE);
getConfigurationStub.withArgs('debugpy').returns(createMoqConfiguration(testParams.justMyCodeSetting));
const debugConfig = await resolveDebugConfiguration(workspaceFolder, {
...launch,
debugStdLib: testParams.debugStdLib,
justMyCode: testParams.justMyCode,
});
expect(debugConfig).to.have.property('justMyCode', testParams.expectedResult);
Expand Down Expand Up @@ -930,6 +930,7 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
request: requestType,
type: 'python',
name: '',
justMyCode: false,
...settings,
};
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
Expand Down
1 change: 1 addition & 0 deletions src/test/unittest/extensionInit.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ suite('Debugging - register Debugging', () => {
sinon.assert.calledWithExactly(registerCommandStub, Commands.ClearStorage, sinon.match.any);
expect(registerCommandStub.callCount).to.be.equal(5);
});

test('Activation will register the Debug adapter factories', async () => {
registerDebugger(context.object);

Expand Down

0 comments on commit 81f79ed

Please sign in to comment.