@@ -9,7 +9,7 @@ import { EOL } from 'os';
99import * as path from 'path' ;
1010import { SemVer } from 'semver' ;
1111import * as TypeMoq from 'typemoq' ;
12- import { Range , Selection , TextDocument , TextEditor , TextLine , Uri } from 'vscode' ;
12+ import { Position , Range , Selection , TextDocument , TextEditor , TextLine , Uri } from 'vscode' ;
1313import { IApplicationShell , IDocumentManager } from '../../../client/common/application/types' ;
1414import { EXTENSION_ROOT_DIR , PYTHON_LANGUAGE } from '../../../client/common/constants' ;
1515import '../../../client/common/extensions' ;
@@ -271,8 +271,8 @@ suite('Terminal - Code Execution Helper', () => {
271271 document . verify ( ( doc ) => doc . save ( ) , TypeMoq . Times . never ( ) ) ;
272272 } ) ;
273273
274- test ( 'Returns current line if nothing is selected ' , async ( ) => {
275- const lineContents = 'Line Contents' ;
274+ test ( 'Selection is empty, return current line ' , async ( ) => {
275+ const lineContents = ' Line Contents' ;
276276 editor . setup ( ( e ) => e . selection ) . returns ( ( ) => new Selection ( 3 , 0 , 3 , 0 ) ) ;
277277 const textLine = TypeMoq . Mock . ofType < TextLine > ( ) ;
278278 textLine . setup ( ( t ) => t . text ) . returns ( ( ) => lineContents ) ;
@@ -282,17 +282,137 @@ suite('Terminal - Code Execution Helper', () => {
282282 expect ( content ) . to . be . equal ( lineContents ) ;
283283 } ) ;
284284
285- test ( 'Returns selected text' , async ( ) => {
286- const lineContents = 'Line Contents' ;
287- editor . setup ( ( e ) => e . selection ) . returns ( ( ) => new Selection ( 3 , 0 , 10 , 5 ) ) ;
285+ test ( 'Single line: text selection without whitespace ' , async ( ) => {
286+ // This test verifies following case:
287+ // 1: if (x):
288+ // 2: print(x)
289+ // 3: ↑------↑ <--- selection range
290+ const expected = ' print(x)' ;
291+ editor . setup ( ( e ) => e . selection ) . returns ( ( ) => new Selection ( 2 , 4 , 2 , 12 ) ) ;
288292 const textLine = TypeMoq . Mock . ofType < TextLine > ( ) ;
289- textLine . setup ( ( t ) => t . text ) . returns ( ( ) => lineContents ) ;
293+ textLine . setup ( ( t ) => t . text ) . returns ( ( ) => ' print(x)' ) ;
294+ document . setup ( ( d ) => d . lineAt ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => textLine . object ) ;
295+ document . setup ( ( d ) => d . getText ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => 'print(x)' ) ;
296+
297+ const content = await helper . getSelectedTextToExecute ( editor . object ) ;
298+ expect ( content ) . to . be . equal ( expected ) ;
299+ } ) ;
300+
301+ test ( 'Single line: partial text selection without whitespace ' , async ( ) => {
302+ // This test verifies following case:
303+ // 1: if (isPrime(x) || isFibonacci(x)):
304+ // 2: ↑--------↑ <--- selection range
305+ const expected = 'isPrime(x)' ;
306+ editor . setup ( ( e ) => e . selection ) . returns ( ( ) => new Selection ( 1 , 4 , 1 , 14 ) ) ;
307+ const textLine = TypeMoq . Mock . ofType < TextLine > ( ) ;
308+ textLine . setup ( ( t ) => t . text ) . returns ( ( ) => 'if (isPrime(x) || isFibonacci(x)):' ) ;
309+ document . setup ( ( d ) => d . lineAt ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => textLine . object ) ;
310+ document . setup ( ( d ) => d . getText ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => 'isPrime(x)' ) ;
311+
312+ const content = await helper . getSelectedTextToExecute ( editor . object ) ;
313+ expect ( content ) . to . be . equal ( expected ) ;
314+ } ) ;
315+
316+ test ( 'Multi-line: text selection without whitespace ' , async ( ) => {
317+ // This test verifies following case:
318+ // 1: def calc(m, n):
319+ // ↓<------------------------------- selection start
320+ // 2: print(m)
321+ // 3: print(n)
322+ // ↑<------------------------ selection end
323+ const expected = ' print(m)\n print(n)' ;
324+ const selection = new Selection ( 2 , 4 , 3 , 12 ) ;
325+ editor . setup ( ( e ) => e . selection ) . returns ( ( ) => selection ) ;
326+ const textLine = TypeMoq . Mock . ofType < TextLine > ( ) ;
327+ textLine . setup ( ( t ) => t . text ) . returns ( ( ) => 'def calc(m, n):' ) ;
328+ const textLine2 = TypeMoq . Mock . ofType < TextLine > ( ) ;
329+ textLine2 . setup ( ( t ) => t . text ) . returns ( ( ) => ' print(m)' ) ;
330+ const textLine3 = TypeMoq . Mock . ofType < TextLine > ( ) ;
331+ textLine3 . setup ( ( t ) => t . text ) . returns ( ( ) => ' print(n)' ) ;
332+ const textLines = [ textLine , textLine2 , textLine3 ] ;
333+ document . setup ( ( d ) => d . lineAt ( TypeMoq . It . isAny ( ) ) ) . returns ( ( r : number ) => textLines [ r - 1 ] . object ) ;
334+ document
335+ . setup ( ( d ) => d . getText ( new Range ( selection . start , selection . end ) ) )
336+ . returns ( ( ) => 'print(m)\n print(n)' ) ;
337+ document
338+ . setup ( ( d ) => d . getText ( new Range ( new Position ( selection . start . line , 0 ) , selection . end ) ) )
339+ . returns ( ( ) => ' print(m)\n print(n)' ) ;
340+
341+ const content = await helper . getSelectedTextToExecute ( editor . object ) ;
342+ expect ( content ) . to . be . equal ( expected ) ;
343+ } ) ;
344+
345+ test ( 'Multi-line: text selection without whitespace and partial last line ' , async ( ) => {
346+ // This test verifies following case:
347+ // 1: def calc(m, n):
348+ // ↓<------------------------------ selection start
349+ // 2: if (m == 0):
350+ // 3: return n + 1
351+ // ↑<------------------- selection end (notice " + 1" is not selected)
352+ const expected = ' if (m == 0):\n return n' ;
353+ const selection = new Selection ( 2 , 4 , 3 , 16 ) ;
354+ editor . setup ( ( e ) => e . selection ) . returns ( ( ) => selection ) ;
355+ const textLine = TypeMoq . Mock . ofType < TextLine > ( ) ;
356+ textLine . setup ( ( t ) => t . text ) . returns ( ( ) => 'def calc(m, n):' ) ;
357+ const textLine2 = TypeMoq . Mock . ofType < TextLine > ( ) ;
358+ textLine2 . setup ( ( t ) => t . text ) . returns ( ( ) => ' if (m == 0):' ) ;
359+ const textLine3 = TypeMoq . Mock . ofType < TextLine > ( ) ;
360+ textLine3 . setup ( ( t ) => t . text ) . returns ( ( ) => ' return n + 1' ) ;
361+ const textLines = [ textLine , textLine2 , textLine3 ] ;
362+ document . setup ( ( d ) => d . lineAt ( TypeMoq . It . isAny ( ) ) ) . returns ( ( r : number ) => textLines [ r - 1 ] . object ) ;
363+ document
364+ . setup ( ( d ) => d . getText ( new Range ( selection . start , selection . end ) ) )
365+ . returns ( ( ) => 'if (m == 0):\n return n' ) ;
366+ document
367+ . setup ( ( d ) =>
368+ d . getText ( new Range ( new Position ( selection . start . line , 4 ) , new Position ( selection . start . line , 16 ) ) )
369+ )
370+ . returns ( ( ) => 'if (m == 0):' ) ;
371+ document
372+ . setup ( ( d ) =>
373+ d . getText ( new Range ( new Position ( selection . start . line , 0 ) , new Position ( selection . end . line , 20 ) ) )
374+ )
375+ . returns ( ( ) => ' if (m == 0):\n return n + 1' ) ;
376+
377+ const content = await helper . getSelectedTextToExecute ( editor . object ) ;
378+ expect ( content ) . to . be . equal ( expected ) ;
379+ } ) ;
380+
381+ test ( 'Multi-line: partial first and last line' , async ( ) => {
382+ // This test verifies following case:
383+ // 1: def calc(m, n):
384+ // ↓<------------------------------- selection start
385+ // 2: if (m > 0
386+ // 3: and n == 0):
387+ // ↑<-------------------- selection end
388+ // 4: pass
389+ const expected = '(m > 0\n and n == 0)' ;
390+ const selection = new Selection ( 2 , 7 , 3 , 19 ) ;
391+ editor . setup ( ( e ) => e . selection ) . returns ( ( ) => selection ) ;
392+ const textLine = TypeMoq . Mock . ofType < TextLine > ( ) ;
393+ textLine . setup ( ( t ) => t . text ) . returns ( ( ) => 'def calc(m, n):' ) ;
394+ const textLine2 = TypeMoq . Mock . ofType < TextLine > ( ) ;
395+ textLine2 . setup ( ( t ) => t . text ) . returns ( ( ) => ' if (m > 0' ) ;
396+ const textLine3 = TypeMoq . Mock . ofType < TextLine > ( ) ;
397+ textLine3 . setup ( ( t ) => t . text ) . returns ( ( ) => ' and n == 0)' ) ;
398+ const textLines = [ textLine , textLine2 , textLine3 ] ;
399+ document . setup ( ( d ) => d . lineAt ( TypeMoq . It . isAny ( ) ) ) . returns ( ( r : number ) => textLines [ r - 1 ] . object ) ;
400+ document
401+ . setup ( ( d ) => d . getText ( new Range ( selection . start , selection . end ) ) )
402+ . returns ( ( ) => '(m > 0\n and n == 0)' ) ;
403+ document
404+ . setup ( ( d ) =>
405+ d . getText ( new Range ( new Position ( selection . start . line , 7 ) , new Position ( selection . start . line , 13 ) ) )
406+ )
407+ . returns ( ( ) => '(m > 0' ) ;
290408 document
291- . setup ( ( d ) => d . getText ( TypeMoq . It . isAny ( ) ) )
292- . returns ( ( r : Range ) => `${ r . start . line } .${ r . start . character } .${ r . end . line } .${ r . end . character } ` ) ;
409+ . setup ( ( d ) =>
410+ d . getText ( new Range ( new Position ( selection . start . line , 0 ) , new Position ( selection . end . line , 19 ) ) )
411+ )
412+ . returns ( ( ) => ' if (m > 0\n and n == 0)' ) ;
293413
294414 const content = await helper . getSelectedTextToExecute ( editor . object ) ;
295- expect ( content ) . to . be . equal ( '3.0.10.5' ) ;
415+ expect ( content ) . to . be . equal ( expected ) ;
296416 } ) ;
297417
298418 test ( 'saveFileIfDirty will not fail if file is not opened' , async ( ) => {
0 commit comments