Skip to content

Commit

Permalink
Ensure code is executed when last line of selected code is indented (#…
Browse files Browse the repository at this point in the history
…2222)

* Ensure code is executed when last line of selected code is indented
* Tweak news entry
* Address code review issues
* Fix code review comments
  • Loading branch information
DonJayamanne authored Sep 6, 2018
1 parent 388e9c1 commit b5e1e44
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 18 deletions.
1 change: 1 addition & 0 deletions news/2 Fixes/2167.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Ensure code is executed when the last line of selected code is indented.
14 changes: 10 additions & 4 deletions pythonFiles/normalizeForInterpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,15 @@ def normalize_lines(source):
"""
lines = source.splitlines(False)
# If we have two blank lines, then add two blank lines.
# Do not trim the spaces, if we have blank lines with spaces, its possible
# we have indented code.
if (len(lines) > 1 and len(''.join(lines[-2:])) == 0) \
or source.endswith(('\n\n', '\r\n\r\n')):
trailing_newline = os.linesep * 2
# Find out if we have any trailing blank lines
if len(lines[-1].strip()) == 0 or source.endswith('\n'):
trailing_newline = '\n'
elif len(lines[-1].strip()) == 0 or source.endswith(('\n', '\r\n')):
trailing_newline = os.linesep
else:
trailing_newline = ''

Expand All @@ -95,7 +101,7 @@ def normalize_lines(source):
# Step 2: Add blank lines between each global statement block.
# A consequtive single lines blocks of code will be treated as a single statement,
# just to ensure we do not unnecessarily add too many blank lines.
source = '\n'.join(lines)
source = os.linesep.join(lines)
tokens = _tokenize(source)
dedent_indexes = (spos[0] for (toknum, tokval, spos, epos, line) in tokens
if toknum == token.DEDENT and _indent_size(line) == 0)
Expand All @@ -105,7 +111,7 @@ def normalize_lines(source):
for line_number in filter(lambda x: x > 1, start_positions):
lines.insert(line_number-1, '')

sys.stdout.write('\n'.join(lines) + trailing_newline)
sys.stdout.write(os.linesep.join(lines) + trailing_newline)
sys.stdout.flush()


Expand Down
15 changes: 10 additions & 5 deletions src/test/terminals/codeExecution/helper.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,16 @@ suite('Terminal - Code Execution Helper', () => {
const expectedCode = await fs.readFile(path.join(TEST_FILES_PATH, `sample${fileNameSuffix}_normalized.py`), 'utf8');
await ensureBlankLinesAreRemoved(code, expectedCode);
});
// test(`Ensure blank lines are removed, including leading empty lines (${fileName})`, async () => {
// const code = await fs.readFile(path.join(TEST_FILES_PATH, `${fileName}_raw.py`), 'utf8');
// const expectedCode = await fs.readFile(path.join(TEST_FILES_PATH, `${fileName}_normalized.py`), 'utf8');
// await ensureBlankLinesAreRemoved(['', '', ''].join(EOL) + EOL + code, expectedCode);
// });
test(`Ensure last two blank lines are preserved (Sample${fileNameSuffix})`, async () => {
const code = await fs.readFile(path.join(TEST_FILES_PATH, `sample${fileNameSuffix}_raw.py`), 'utf8');
const expectedCode = await fs.readFile(path.join(TEST_FILES_PATH, `sample${fileNameSuffix}_normalized.py`), 'utf8');
await ensureBlankLinesAreRemoved(code + EOL, expectedCode + EOL);
});
test(`Ensure last two blank lines are preserved even if we have more than 2 trailing blank lines (Sample${fileNameSuffix})`, async () => {
const code = await fs.readFile(path.join(TEST_FILES_PATH, `sample${fileNameSuffix}_raw.py`), 'utf8');
const expectedCode = await fs.readFile(path.join(TEST_FILES_PATH, `sample${fileNameSuffix}_normalized.py`), 'utf8');
await ensureBlankLinesAreRemoved(code + EOL + EOL + EOL + EOL, expectedCode + EOL);
});
});
test('Display message if there\s no active file', async () => {
documentManager.setup(doc => doc.activeTextEditor).returns(() => undefined);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// tslint:disable:no-multiline-string no-trailing-whitespace
// tslint:disable:no-multiline-string no-trailing-whitespace max-func-body-length

import { expect } from 'chai';
import * as path from 'path';
import * as TypeMoq from 'typemoq';
import { Disposable, Uri, WorkspaceFolder } from 'vscode';
import { ICommandManager, IDocumentManager, IWorkspaceService } from '../../../client/common/application/types';
import { noop } from '../../../client/common/core.utils';
import { IFileSystem, IPlatformService } from '../../../client/common/platform/types';
import { ITerminalService, ITerminalServiceFactory } from '../../../client/common/terminal/types';
import { IConfigurationService, IPythonSettings, ITerminalSettings } from '../../../client/common/types';
Expand All @@ -17,9 +18,7 @@ import { TerminalCodeExecutionProvider } from '../../../client/terminals/codeExe
import { ICodeExecutionService } from '../../../client/terminals/types';
import { PYTHON_PATH } from '../../common';

// tslint:disable-next-line:max-func-body-length
suite('Terminal - Code Execution', () => {
// tslint:disable-next-line:max-func-body-length
['Terminal Execution', 'Repl Execution', 'Django Execution'].forEach(testSuiteName => {
let terminalSettings: TypeMoq.IMock<ITerminalSettings>;
let terminalService: TypeMoq.IMock<ITerminalService>;
Expand All @@ -46,7 +45,6 @@ suite('Terminal - Code Execution', () => {
disposables = [];
});

// tslint:disable-next-line:max-func-body-length
setup(() => {
terminalFactory = TypeMoq.Mock.ofType<ITerminalServiceFactory>();
terminalSettings = TypeMoq.Mock.ofType<ITerminalSettings>();
Expand Down Expand Up @@ -76,8 +74,7 @@ suite('Terminal - Code Execution', () => {
case 'Django Execution': {
isDjangoRepl = true;
workspace.setup(w => w.onDidChangeWorkspaceFolders(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => {
// tslint:disable-next-line:no-empty
return { dispose: () => { } };
return { dispose: noop };
});
executor = new DjangoShellCodeExecutionProvider(terminalFactory.object, configService.object, workspace.object, documentManager.object,
platform.object, commandManager.object, fileSystem.object, disposables);
Expand Down Expand Up @@ -119,7 +116,6 @@ suite('Terminal - Code Execution', () => {
});
});

// tslint:disable-next-line:max-func-body-length
suite(testSuiteName, () => {
setup(() => {
terminalFactory.setup(f => f.getTerminalService(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => terminalService.object);
Expand Down Expand Up @@ -323,8 +319,7 @@ suite('Terminal - Code Execution', () => {
terminalService.setup(t => t.onDidCloseTerminal(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((callback => {
closeTerminalCallback = callback;
return {
// tslint:disable-next-line:no-empty
dispose: () => void 0
dispose: noop
};
}));

Expand Down

0 comments on commit b5e1e44

Please sign in to comment.