@@ -6,7 +6,7 @@ import { Container } from 'inversify';
66import * as os from 'os' ;
77import * as path from 'path' ;
88import * as TypeMoq from 'typemoq' ;
9- import { CancellationTokenSource , OutputChannel , TextDocument , Uri , WorkspaceFolder } from 'vscode' ;
9+ import { CancellationTokenSource , DiagnosticSeverity , OutputChannel , TextDocument , Uri , WorkspaceFolder } from 'vscode' ;
1010import { IWorkspaceService } from '../../client/common/application/types' ;
1111import { IFileSystem , IPlatformService } from '../../client/common/platform/types' ;
1212import { IPythonToolExecutionService } from '../../client/common/process/types' ;
@@ -19,7 +19,7 @@ import { ILinterManager } from '../../client/linters/types';
1919import { MockLintingSettings } from '../mockClasses' ;
2020
2121// tslint:disable-next-line:max-func-body-length
22- suite ( 'Linting - Pylintrc search ' , ( ) => {
22+ suite ( 'Linting - Pylint ' , ( ) => {
2323 const basePath = '/user/a/b/c/d' ;
2424 const pylintrc = 'pylintrc' ;
2525 const dotPylintrc = '.pylintrc' ;
@@ -199,4 +199,47 @@ suite('Linting - Pylintrc search', () => {
199199 expect ( execInfo ! . args . findIndex ( x => x . indexOf ( '--disable=all' ) >= 0 ) ,
200200 'Minimal args passed to pylint while pylintrc exists.' ) . to . be . eq ( expectedMinArgs ? 0 : - 1 ) ;
201201 }
202+ test ( 'Negative column numbers should be treated 0' , async ( ) => {
203+ const fileFolder = '/user/a/b/c' ;
204+ const outputChannel = TypeMoq . Mock . ofType < OutputChannel > ( ) ;
205+ const pylinter = new Pylint ( outputChannel . object , serviceContainer ) ;
206+
207+ const document = TypeMoq . Mock . ofType < TextDocument > ( ) ;
208+ document . setup ( x => x . uri ) . returns ( ( ) => Uri . file ( path . join ( fileFolder , 'test.py' ) ) ) ;
209+
210+ const wsf = TypeMoq . Mock . ofType < WorkspaceFolder > ( ) ;
211+ wsf . setup ( x => x . uri ) . returns ( ( ) => Uri . file ( fileFolder ) ) ;
212+
213+ workspace . setup ( x => x . getWorkspaceFolder ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => wsf . object ) ;
214+
215+ const linterOutput = [ 'No config file found, using default configuration' ,
216+ '************* Module test' ,
217+ '1,1,convention,C0111:Missing module docstring' ,
218+ '3,-1,error,E1305:Too many arguments for format string' ] . join ( os . EOL ) ;
219+ execService
220+ . setup ( x => x . exec ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) )
221+ . returns ( ( ) => Promise . resolve ( { stdout : linterOutput , stderr : '' } ) ) ;
222+
223+ const lintSettings = new MockLintingSettings ( ) ;
224+ lintSettings . pylintUseMinimalCheckers = false ;
225+ lintSettings . maxNumberOfProblems = 1000 ;
226+ lintSettings . pylintPath = 'pyLint' ;
227+ lintSettings . pylintEnabled = true ;
228+ lintSettings . pylintCategorySeverity = {
229+ convention : DiagnosticSeverity . Hint ,
230+ error : DiagnosticSeverity . Error ,
231+ fatal : DiagnosticSeverity . Error ,
232+ refactor : DiagnosticSeverity . Hint ,
233+ warning : DiagnosticSeverity . Warning
234+ } ;
235+
236+ const settings = TypeMoq . Mock . ofType < IPythonSettings > ( ) ;
237+ settings . setup ( x => x . linting ) . returns ( ( ) => lintSettings ) ;
238+ config . setup ( x => x . getSettings ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => settings . object ) ;
239+
240+ const messages = await pylinter . lint ( document . object , new CancellationTokenSource ( ) . token ) ;
241+ expect ( messages ) . to . be . lengthOf ( 2 ) ;
242+ expect ( messages [ 0 ] . column ) . to . be . equal ( 1 ) ;
243+ expect ( messages [ 1 ] . column ) . to . be . equal ( 0 ) ;
244+ } ) ;
202245} ) ;
0 commit comments