Skip to content

Commit 48036ff

Browse files
authored
Fix failing Prospector unit tests and add more tests for linters (#1837)
* Fix failing Prospector unit tests * Add more tests for relative prospector paths * Udpated readme
1 parent 510008f commit 48036ff

File tree

3 files changed

+129
-123
lines changed

3 files changed

+129
-123
lines changed

news/3 Code Health/1836.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix failing Prospector unit tests and add more tests for linters (with and without workspaces).

src/test/common/moduleInstaller.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const info: PythonInterpreter = {
4242
sysVersion: ''
4343
};
4444

45-
suite('Module Installerx', () => {
45+
suite('Module Installer', () => {
4646
[undefined, Uri.file(__filename)].forEach(resource => {
4747
let ioc: UnitTestIocContainer;
4848
let mockTerminalService: TypeMoq.IMock<ITerminalService>;

src/test/linters/lint.args.test.ts

Lines changed: 127 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
'use strict';
55

6-
// tslint:disable:no-any
6+
// tslint:disable:no-any max-func-body-length
77

88
import { expect } from 'chai';
99
import { Container } from 'inversify';
1010
import * as path from 'path';
1111
import * as TypeMoq from 'typemoq';
12-
import { CancellationTokenSource, OutputChannel, TextDocument, Uri } from 'vscode';
12+
import { CancellationTokenSource, OutputChannel, TextDocument, Uri, WorkspaceFolder } from 'vscode';
1313
import { IDocumentManager, IWorkspaceService } from '../../client/common/application/types';
1414
import '../../client/common/extensions';
1515
import { IFileSystem, IPlatformService } from '../../client/common/platform/types';
@@ -29,127 +29,132 @@ import { Pylint } from '../../client/linters/pylint';
2929
import { ILinterManager, ILintingEngine } from '../../client/linters/types';
3030
import { initialize } from '../initialize';
3131

32-
// tslint:disable-next-line:max-func-body-length
3332
suite('Linting - Arguments', () => {
34-
let interpreterService: TypeMoq.IMock<IInterpreterService>;
35-
let engine: TypeMoq.IMock<ILintingEngine>;
36-
let configService: TypeMoq.IMock<IConfigurationService>;
37-
let docManager: TypeMoq.IMock<IDocumentManager>;
38-
let settings: TypeMoq.IMock<IPythonSettings>;
39-
let lm: ILinterManager;
40-
let serviceContainer: ServiceContainer;
41-
let document: TypeMoq.IMock<TextDocument>;
42-
let outputChannel: TypeMoq.IMock<OutputChannel>;
43-
let workspaceService: TypeMoq.IMock<IWorkspaceService>;
44-
const cancellationToken = new CancellationTokenSource().token;
45-
46-
suiteSetup(initialize);
47-
setup(async () => {
48-
const cont = new Container();
49-
const serviceManager = new ServiceManager(cont);
50-
51-
serviceContainer = new ServiceContainer(cont);
52-
outputChannel = TypeMoq.Mock.ofType<OutputChannel>();
53-
54-
const fs = TypeMoq.Mock.ofType<IFileSystem>();
55-
fs.setup(x => x.fileExists(TypeMoq.It.isAny())).returns(() => new Promise<boolean>((resolve, reject) => resolve(true)));
56-
fs.setup(x => x.arePathsSame(TypeMoq.It.isAnyString(), TypeMoq.It.isAnyString())).returns(() => true);
57-
serviceManager.addSingletonInstance<IFileSystem>(IFileSystem, fs.object);
58-
59-
serviceManager.addSingletonInstance(IOutputChannel, outputChannel.object);
60-
61-
interpreterService = TypeMoq.Mock.ofType<IInterpreterService>();
62-
serviceManager.addSingletonInstance<IInterpreterService>(IInterpreterService, interpreterService.object);
63-
64-
engine = TypeMoq.Mock.ofType<ILintingEngine>();
65-
serviceManager.addSingletonInstance<ILintingEngine>(ILintingEngine, engine.object);
66-
67-
docManager = TypeMoq.Mock.ofType<IDocumentManager>();
68-
serviceManager.addSingletonInstance<IDocumentManager>(IDocumentManager, docManager.object);
69-
70-
const lintSettings = TypeMoq.Mock.ofType<ILintingSettings>();
71-
lintSettings.setup(x => x.enabled).returns(() => true);
72-
lintSettings.setup(x => x.lintOnSave).returns(() => true);
73-
74-
settings = TypeMoq.Mock.ofType<IPythonSettings>();
75-
settings.setup(x => x.linting).returns(() => lintSettings.object);
76-
77-
configService = TypeMoq.Mock.ofType<IConfigurationService>();
78-
configService.setup(x => x.getSettings(TypeMoq.It.isAny())).returns(() => settings.object);
79-
serviceManager.addSingletonInstance<IConfigurationService>(IConfigurationService, configService.object);
80-
81-
workspaceService = TypeMoq.Mock.ofType<IWorkspaceService>();
82-
serviceManager.addSingletonInstance<IWorkspaceService>(IWorkspaceService, workspaceService.object);
83-
84-
const logger = TypeMoq.Mock.ofType<ILogger>();
85-
serviceManager.addSingletonInstance<ILogger>(ILogger, logger.object);
86-
87-
const installer = TypeMoq.Mock.ofType<IInstaller>();
88-
serviceManager.addSingletonInstance<IInstaller>(IInstaller, installer.object);
89-
90-
const platformService = TypeMoq.Mock.ofType<IPlatformService>();
91-
serviceManager.addSingletonInstance<IPlatformService>(IPlatformService, platformService.object);
92-
93-
lm = new LinterManager(serviceContainer);
94-
serviceManager.addSingletonInstance<ILinterManager>(ILinterManager, lm);
95-
document = TypeMoq.Mock.ofType<TextDocument>();
96-
});
97-
98-
async function testLinter(linter: BaseLinter, fileUri: Uri, expectedArgs: string[]) {
99-
document.setup(d => d.uri).returns(() => fileUri);
100-
101-
let invoked = false;
102-
(linter as any).run = (args, doc, token) => {
103-
expect(args).to.deep.equal(expectedArgs);
104-
invoked = true;
105-
return Promise.resolve([]);
106-
};
107-
await linter.lint(document.object, cancellationToken);
108-
expect(invoked).to.be.equal(true, 'method not invoked');
109-
}
110-
[Uri.file(path.join('users', 'development path to', 'one.py')), Uri.file(path.join('users', 'development', 'one.py'))].forEach(fileUri => {
111-
test(`Flake8 (${fileUri.fsPath.indexOf(' ') > 0 ? 'with spaces' : 'without spaces'})`, async () => {
112-
const linter = new Flake8(outputChannel.object, serviceContainer);
113-
const expectedArgs = ['--format=%(row)d,%(col)d,%(code).1s,%(code)s:%(text)s', fileUri.fsPath];
114-
await testLinter(linter, fileUri, expectedArgs);
115-
});
116-
test(`Pep8 (${fileUri.fsPath.indexOf(' ') > 0 ? 'with spaces' : 'without spaces'})`, async () => {
117-
const linter = new Pep8(outputChannel.object, serviceContainer);
118-
const expectedArgs = ['--format=%(row)d,%(col)d,%(code).1s,%(code)s:%(text)s', fileUri.fsPath];
119-
await testLinter(linter, fileUri, expectedArgs);
120-
});
121-
test(`Prospector (${fileUri.fsPath.indexOf(' ') > 0 ? 'with spaces' : 'without spaces'})`, async () => {
122-
const linter = new Prospector(outputChannel.object, serviceContainer);
123-
const expectedArgs = ['--absolute-paths', '--output-format=json', fileUri.fsPath];
124-
await testLinter(linter, fileUri, expectedArgs);
125-
});
126-
test(`Pylama (${fileUri.fsPath.indexOf(' ') > 0 ? 'with spaces' : 'without spaces'})`, async () => {
127-
const linter = new PyLama(outputChannel.object, serviceContainer);
128-
const expectedArgs = ['--format=parsable', fileUri.fsPath];
129-
await testLinter(linter, fileUri, expectedArgs);
130-
});
131-
test(`MyPy (${fileUri.fsPath.indexOf(' ') > 0 ? 'with spaces' : 'without spaces'})`, async () => {
132-
const linter = new MyPy(outputChannel.object, serviceContainer);
133-
const expectedArgs = [fileUri.fsPath];
134-
await testLinter(linter, fileUri, expectedArgs);
135-
});
136-
test(`Pydocstyle (${fileUri.fsPath.indexOf(' ') > 0 ? 'with spaces' : 'without spaces'})`, async () => {
137-
const linter = new PyDocStyle(outputChannel.object, serviceContainer);
138-
const expectedArgs = [fileUri.fsPath];
139-
await testLinter(linter, fileUri, expectedArgs);
140-
});
141-
test(`Pylint (${fileUri.fsPath.indexOf(' ') > 0 ? 'with spaces' : 'without spaces'})`, async () => {
142-
const linter = new Pylint(outputChannel.object, serviceContainer);
143-
document.setup(d => d.uri).returns(() => fileUri);
144-
145-
let invoked = false;
146-
(linter as any).run = (args, doc, token) => {
147-
expect(args[args.length - 1]).to.equal(fileUri.fsPath);
148-
invoked = true;
149-
return Promise.resolve([]);
150-
};
151-
await linter.lint(document.object, cancellationToken);
152-
expect(invoked).to.be.equal(true, 'method not invoked');
33+
[undefined, path.join('users', 'dev_user')].forEach(workspaceUri => {
34+
[Uri.file(path.join('users', 'dev_user', 'development path to', 'one.py')), Uri.file(path.join('users', 'dev_user', 'development', 'one.py'))].forEach(fileUri => {
35+
suite(`File path ${fileUri.fsPath.indexOf(' ') > 0 ? 'with' : 'without'} spaces and ${workspaceUri ? 'without' : 'with'} a workspace`, () => {
36+
let interpreterService: TypeMoq.IMock<IInterpreterService>;
37+
let engine: TypeMoq.IMock<ILintingEngine>;
38+
let configService: TypeMoq.IMock<IConfigurationService>;
39+
let docManager: TypeMoq.IMock<IDocumentManager>;
40+
let settings: TypeMoq.IMock<IPythonSettings>;
41+
let lm: ILinterManager;
42+
let serviceContainer: ServiceContainer;
43+
let document: TypeMoq.IMock<TextDocument>;
44+
let outputChannel: TypeMoq.IMock<OutputChannel>;
45+
let workspaceService: TypeMoq.IMock<IWorkspaceService>;
46+
const cancellationToken = new CancellationTokenSource().token;
47+
suiteSetup(initialize);
48+
setup(async () => {
49+
const cont = new Container();
50+
const serviceManager = new ServiceManager(cont);
51+
52+
serviceContainer = new ServiceContainer(cont);
53+
outputChannel = TypeMoq.Mock.ofType<OutputChannel>();
54+
55+
const fs = TypeMoq.Mock.ofType<IFileSystem>();
56+
fs.setup(x => x.fileExists(TypeMoq.It.isAny())).returns(() => new Promise<boolean>((resolve, reject) => resolve(true)));
57+
fs.setup(x => x.arePathsSame(TypeMoq.It.isAnyString(), TypeMoq.It.isAnyString())).returns(() => true);
58+
serviceManager.addSingletonInstance<IFileSystem>(IFileSystem, fs.object);
59+
60+
serviceManager.addSingletonInstance(IOutputChannel, outputChannel.object);
61+
62+
interpreterService = TypeMoq.Mock.ofType<IInterpreterService>();
63+
serviceManager.addSingletonInstance<IInterpreterService>(IInterpreterService, interpreterService.object);
64+
65+
engine = TypeMoq.Mock.ofType<ILintingEngine>();
66+
serviceManager.addSingletonInstance<ILintingEngine>(ILintingEngine, engine.object);
67+
68+
docManager = TypeMoq.Mock.ofType<IDocumentManager>();
69+
serviceManager.addSingletonInstance<IDocumentManager>(IDocumentManager, docManager.object);
70+
71+
const lintSettings = TypeMoq.Mock.ofType<ILintingSettings>();
72+
lintSettings.setup(x => x.enabled).returns(() => true);
73+
lintSettings.setup(x => x.lintOnSave).returns(() => true);
74+
75+
settings = TypeMoq.Mock.ofType<IPythonSettings>();
76+
settings.setup(x => x.linting).returns(() => lintSettings.object);
77+
78+
configService = TypeMoq.Mock.ofType<IConfigurationService>();
79+
configService.setup(x => x.getSettings(TypeMoq.It.isAny())).returns(() => settings.object);
80+
serviceManager.addSingletonInstance<IConfigurationService>(IConfigurationService, configService.object);
81+
82+
const workspaceFolder: WorkspaceFolder | undefined = workspaceUri ? { uri: Uri.file(workspaceUri), index: 0, name: '' } : undefined;
83+
workspaceService = TypeMoq.Mock.ofType<IWorkspaceService>();
84+
workspaceService.setup(w => w.getWorkspaceFolder(TypeMoq.It.isAny())).returns(() => workspaceFolder);
85+
serviceManager.addSingletonInstance<IWorkspaceService>(IWorkspaceService, workspaceService.object);
86+
87+
const logger = TypeMoq.Mock.ofType<ILogger>();
88+
serviceManager.addSingletonInstance<ILogger>(ILogger, logger.object);
89+
90+
const installer = TypeMoq.Mock.ofType<IInstaller>();
91+
serviceManager.addSingletonInstance<IInstaller>(IInstaller, installer.object);
92+
93+
const platformService = TypeMoq.Mock.ofType<IPlatformService>();
94+
serviceManager.addSingletonInstance<IPlatformService>(IPlatformService, platformService.object);
95+
96+
lm = new LinterManager(serviceContainer);
97+
serviceManager.addSingletonInstance<ILinterManager>(ILinterManager, lm);
98+
document = TypeMoq.Mock.ofType<TextDocument>();
99+
});
100+
101+
async function testLinter(linter: BaseLinter, expectedArgs: string[]) {
102+
document.setup(d => d.uri).returns(() => fileUri);
103+
104+
let invoked = false;
105+
(linter as any).run = (args, doc, token) => {
106+
expect(args).to.deep.equal(expectedArgs);
107+
invoked = true;
108+
return Promise.resolve([]);
109+
};
110+
await linter.lint(document.object, cancellationToken);
111+
expect(invoked).to.be.equal(true, 'method not invoked');
112+
}
113+
test('Flake8', async () => {
114+
const linter = new Flake8(outputChannel.object, serviceContainer);
115+
const expectedArgs = ['--format=%(row)d,%(col)d,%(code).1s,%(code)s:%(text)s', fileUri.fsPath];
116+
await testLinter(linter, expectedArgs);
117+
});
118+
test('Pep8', async () => {
119+
const linter = new Pep8(outputChannel.object, serviceContainer);
120+
const expectedArgs = ['--format=%(row)d,%(col)d,%(code).1s,%(code)s:%(text)s', fileUri.fsPath];
121+
await testLinter(linter, expectedArgs);
122+
});
123+
test('Prospector', async () => {
124+
const linter = new Prospector(outputChannel.object, serviceContainer);
125+
const expectedPath = workspaceUri ? path.relative(workspaceUri, fileUri.fsPath) : path.basename(fileUri.fsPath);
126+
const expectedArgs = ['--absolute-paths', '--output-format=json', expectedPath];
127+
await testLinter(linter, expectedArgs);
128+
});
129+
test('Pylama', async () => {
130+
const linter = new PyLama(outputChannel.object, serviceContainer);
131+
const expectedArgs = ['--format=parsable', fileUri.fsPath];
132+
await testLinter(linter, expectedArgs);
133+
});
134+
test('MyPy', async () => {
135+
const linter = new MyPy(outputChannel.object, serviceContainer);
136+
const expectedArgs = [fileUri.fsPath];
137+
await testLinter(linter, expectedArgs);
138+
});
139+
test('Pydocstyle', async () => {
140+
const linter = new PyDocStyle(outputChannel.object, serviceContainer);
141+
const expectedArgs = [fileUri.fsPath];
142+
await testLinter(linter, expectedArgs);
143+
});
144+
test('Pylint', async () => {
145+
const linter = new Pylint(outputChannel.object, serviceContainer);
146+
document.setup(d => d.uri).returns(() => fileUri);
147+
148+
let invoked = false;
149+
(linter as any).run = (args, doc, token) => {
150+
expect(args[args.length - 1]).to.equal(fileUri.fsPath);
151+
invoked = true;
152+
return Promise.resolve([]);
153+
};
154+
await linter.lint(document.object, cancellationToken);
155+
expect(invoked).to.be.equal(true, 'method not invoked');
156+
});
157+
});
153158
});
154159
});
155160
});

0 commit comments

Comments
 (0)