mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
adding indentation tests for different languages
This commit is contained in:
parent
e763a3dea3
commit
1f8b9deafa
|
@ -18,12 +18,13 @@ import { NullState } from 'vs/editor/common/languages/nullTokenize';
|
|||
import { AutoIndentOnPaste, IndentationToSpacesCommand, IndentationToTabsCommand } from 'vs/editor/contrib/indentation/browser/indentation';
|
||||
import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
|
||||
import { testCommand } from 'vs/editor/test/browser/testCommand';
|
||||
import { javascriptIndentationRules } from 'vs/editor/test/common/modes/supports/javascriptIndentationRules';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/javascriptOnEnterRules';
|
||||
import { javascriptIndentationRules, phpIndentationRules, rubyIndentationRules } from 'vs/editor/test/common/modes/supports/indentationRules';
|
||||
import { javascriptOnEnterRules, phpOnEnterRules } from 'vs/editor/test/common/modes/supports/onEnterRules';
|
||||
|
||||
enum Language {
|
||||
TypeScript,
|
||||
Ruby
|
||||
Ruby,
|
||||
PHP
|
||||
}
|
||||
|
||||
function testIndentationToSpacesCommand(lines: string[], selection: Selection, tabSize: number, expectedLines: string[], expectedSelection: Selection): void {
|
||||
|
@ -66,10 +67,18 @@ function registerLanguageConfiguration(instantiationService: TestInstantiationSe
|
|||
['[', ']'],
|
||||
['(', ')']
|
||||
],
|
||||
indentationRules: {
|
||||
decreaseIndentPattern: /^\s*([}\]]([,)]?\s*(#|$)|\.[a-zA-Z_]\w*\b)|(end|rescue|ensure|else|elsif)\b|(in|when)\s)/,
|
||||
increaseIndentPattern: /^\s*((begin|class|(private|protected)\s+def|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|in|while|case)|([^#]*\sdo\b)|([^#]*=\s*(case|if|unless)))\b([^#\{;]|(\"|'|\/).*\4)*(#.*)?$/,
|
||||
},
|
||||
indentationRules: rubyIndentationRules,
|
||||
}));
|
||||
break;
|
||||
case Language.PHP:
|
||||
disposables.add(languageConfigurationService.register(languageId, {
|
||||
brackets: [
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')']
|
||||
],
|
||||
indentationRules: phpIndentationRules,
|
||||
onEnterRules: phpOnEnterRules
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
@ -606,6 +615,66 @@ suite('`Full` Auto Indent On Type - TypeScript/JavaScript', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('issue #43244: indent when lambda arrow function is detected, outdent when end is reached', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/43244
|
||||
|
||||
const model = createTextModel([
|
||||
'const array = [1, 2, 3, 4, 5];',
|
||||
'array.map(_)'
|
||||
].join('\n'), languageId, {});
|
||||
disposables.add(model);
|
||||
|
||||
withTestCodeEditor(model, { autoIndent: "full" }, (editor, viewModel, instantiationService) => {
|
||||
registerLanguage(instantiationService, languageId, Language.TypeScript, disposables);
|
||||
editor.setSelection(new Selection(2, 12, 2, 12));
|
||||
viewModel.type("\n", 'keyboard');
|
||||
assert.strictEqual(model.getValue(), [
|
||||
'const array = [1, 2, 3, 4, 5];',
|
||||
'array.map(_',
|
||||
' ',
|
||||
')'
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
|
||||
test('issue #43244: incorrect indentation after if/for/while without braces', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/43244
|
||||
|
||||
const model = createTextModel([
|
||||
'function f() {',
|
||||
' if (condition)',
|
||||
'}'
|
||||
].join('\n'), languageId, {});
|
||||
disposables.add(model);
|
||||
|
||||
withTestCodeEditor(model, { autoIndent: "full" }, (editor, viewModel, instantiationService) => {
|
||||
|
||||
registerLanguage(instantiationService, languageId, Language.TypeScript, disposables);
|
||||
editor.setSelection(new Selection(2, 19, 2, 19));
|
||||
viewModel.type("\n", 'keyboard');
|
||||
assert.strictEqual(model.getValue(), [
|
||||
'function f() {',
|
||||
' if (condition)',
|
||||
' ',
|
||||
'}',
|
||||
].join('\n'));
|
||||
|
||||
viewModel.type("return;");
|
||||
viewModel.type("\n", 'keyboard');
|
||||
assert.strictEqual(model.getValue(), [
|
||||
'function f() {',
|
||||
' if (condition)',
|
||||
' return;',
|
||||
' ',
|
||||
'}',
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
|
||||
// Failing tests...
|
||||
|
||||
test.skip('issue #40115: keep indentation when added', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/40115
|
||||
|
@ -663,41 +732,6 @@ suite('`Full` Auto Indent On Type - TypeScript/JavaScript', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('issue #43244: incorrect indentation after if/for/while without braces', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/43244
|
||||
|
||||
const model = createTextModel([
|
||||
'function f() {',
|
||||
' if (condition)',
|
||||
'}'
|
||||
].join('\n'), languageId, {});
|
||||
disposables.add(model);
|
||||
|
||||
withTestCodeEditor(model, { autoIndent: "full" }, (editor, viewModel, instantiationService) => {
|
||||
|
||||
registerLanguage(instantiationService, languageId, Language.TypeScript, disposables);
|
||||
editor.setSelection(new Selection(2, 19, 2, 19));
|
||||
viewModel.type("\n", 'keyboard');
|
||||
assert.strictEqual(model.getValue(), [
|
||||
'function f() {',
|
||||
' if (condition)',
|
||||
' ',
|
||||
'}',
|
||||
].join('\n'));
|
||||
|
||||
viewModel.type("return;");
|
||||
viewModel.type("\n", 'keyboard');
|
||||
assert.strictEqual(model.getValue(), [
|
||||
'function f() {',
|
||||
' if (condition)',
|
||||
' return;',
|
||||
' ',
|
||||
'}',
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
|
||||
test.skip('issue #208232: incorrect indentation inside of comments', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/208232
|
||||
|
@ -871,28 +905,6 @@ suite('`Full` Auto Indent On Type - TypeScript/JavaScript', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('issue #43244: indent when lambda arrow function is detected, outdent when end is reached', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/43244
|
||||
|
||||
const model = createTextModel([
|
||||
'const array = [1, 2, 3, 4, 5];',
|
||||
'array.map(_)'
|
||||
].join('\n'), languageId, {});
|
||||
disposables.add(model);
|
||||
|
||||
withTestCodeEditor(model, { autoIndent: "full" }, (editor, viewModel, instantiationService) => {
|
||||
registerLanguage(instantiationService, languageId, Language.TypeScript, disposables);
|
||||
editor.setSelection(new Selection(2, 12, 2, 12));
|
||||
viewModel.type("\n", 'keyboard');
|
||||
assert.strictEqual(model.getValue(), [
|
||||
'const array = [1, 2, 3, 4, 5];',
|
||||
'array.map(_',
|
||||
' ',
|
||||
')'
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
|
||||
// Add tests for:
|
||||
// https://github.com/microsoft/vscode/issues/88638
|
||||
|
@ -918,6 +930,8 @@ suite('Auto Indent On Type - Ruby', () => {
|
|||
|
||||
test('issue #198350: in or when incorrectly match non keywords for Ruby', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/198350
|
||||
|
||||
const model = createTextModel("", languageId, {});
|
||||
disposables.add(model);
|
||||
|
||||
|
@ -938,4 +952,66 @@ suite('Auto Indent On Type - Ruby', () => {
|
|||
assert.strictEqual(model.getValue(), " # in ");
|
||||
});
|
||||
});
|
||||
|
||||
// Failing tests...
|
||||
|
||||
test.skip('issue #199846: in or when incorrectly match non keywords for Ruby', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/199846
|
||||
// explanation: happening because the # is detected probably as a comment
|
||||
|
||||
const model = createTextModel("", languageId, {});
|
||||
disposables.add(model);
|
||||
|
||||
withTestCodeEditor(model, { autoIndent: "full" }, (editor, viewModel, instantiationService) => {
|
||||
|
||||
registerLanguage(instantiationService, languageId, Language.Ruby, disposables);
|
||||
|
||||
viewModel.type("method('#foo') do");
|
||||
viewModel.type("\n", 'keyboard');
|
||||
assert.strictEqual(model.getValue(), [
|
||||
"method('#foo') do",
|
||||
" "
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Auto Indent On Type - PHP', () => {
|
||||
|
||||
const languageId = "php-test";
|
||||
let disposables: DisposableStore;
|
||||
|
||||
setup(() => {
|
||||
disposables = new DisposableStore();
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
test('temp issue because there should be at least one passing test in a suite', () => {
|
||||
assert.ok(true);
|
||||
});
|
||||
|
||||
test.skip('issue #199050: should not indent after { detected in a string', () => {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/199050
|
||||
|
||||
const model = createTextModel("$phrase = preg_replace('#(\{1|%s).*#su', '', $phrase);", languageId, {});
|
||||
disposables.add(model);
|
||||
|
||||
withTestCodeEditor(model, { autoIndent: "full" }, (editor, viewModel, instantiationService) => {
|
||||
|
||||
registerLanguage(instantiationService, languageId, Language.PHP, disposables);
|
||||
editor.setSelection(new Selection(1, 54, 1, 54));
|
||||
viewModel.type("\n", 'keyboard');
|
||||
assert.strictEqual(model.getValue(), [
|
||||
"$phrase = preg_replace('#(\{1|%s).*#su', '', $phrase);",
|
||||
""
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ import { BracketSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/bro
|
|||
import { provideSelectionRanges } from 'vs/editor/contrib/smartSelect/browser/smartSelect';
|
||||
import { WordSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/browser/wordSelections';
|
||||
import { createModelServices } from 'vs/editor/test/common/testTextModel';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/javascriptOnEnterRules';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/onEnterRules';
|
||||
import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry';
|
||||
import { ILanguageSelection, ILanguageService } from 'vs/editor/common/languages/language';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
|
|
|
@ -14,7 +14,7 @@ import { Selection } from 'vs/editor/common/core/selection';
|
|||
import { ILanguageService } from 'vs/editor/common/languages/language';
|
||||
import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry';
|
||||
import { getEditOperation, testCommand } from 'vs/editor/test/browser/testCommand';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/javascriptOnEnterRules';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/onEnterRules';
|
||||
import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService';
|
||||
import { withEditorModel } from 'vs/editor/test/common/testTextModel';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
|
|
@ -26,7 +26,7 @@ import { TextModel } from 'vs/editor/common/model/textModel';
|
|||
import { ViewModel } from 'vs/editor/common/viewModel/viewModelImpl';
|
||||
import { OutgoingViewModelEventKind } from 'vs/editor/common/viewModelEventDispatcher';
|
||||
import { ITestCodeEditor, TestCodeEditorInstantiationOptions, createCodeEditorServices, instantiateTestCodeEditor, withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/javascriptOnEnterRules';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/onEnterRules';
|
||||
import { IRelaxedTextModelCreationOptions, createTextModel, instantiateTextModel } from 'vs/editor/test/common/testTextModel';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
|
||||
|
|
|
@ -10,3 +10,15 @@ export const javascriptIndentationRules = {
|
|||
unIndentedLinePattern: /^(\t|[ ])*[ ]\*[^/]*\*\/\s*$|^(\t|[ ])*[ ]\*\/\s*$|^(\t|[ ])*[ ]\*([ ]([^\*]|\*(?!\/))*)?$/,
|
||||
indentNextLinePattern: /^((.*=>\s*)|((.*[^\w]+|\s*)(if|while|for)\s*\(.*\)\s*))$/,
|
||||
};
|
||||
|
||||
export const rubyIndentationRules = {
|
||||
decreaseIndentPattern: /^\s*([}\]]([,)]?\s*(#|$)|\.[a-zA-Z_]\w*\b)|(end|rescue|ensure|else|elsif)\b|(in|when)\s)/,
|
||||
increaseIndentPattern: /^\s*((begin|class|(private|protected)\s+def|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|in|while|case)|([^#]*\sdo\b)|([^#]*=\s*(case|if|unless)))\b([^#\{;]|(\"|'|\/).*\4)*(#.*)?$/,
|
||||
};
|
||||
|
||||
export const phpIndentationRules = {
|
||||
increaseIndentPattern: /({(?!.*}).*|\(|\[|((else(\s)?)?if|else|for(each)?|while|switch|case).*:)\s*((\/[/*].*|)?$|\?>)/,
|
||||
decreaseIndentPattern: /^(.*\*\/)?\s*((\})|(\)+[;,])|(\]\)*[;,])|\b(else:)|\b((end(if|for(each)?|while|switch));))/,
|
||||
};
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
import * as assert from 'assert';
|
||||
import { CharacterPair, IndentAction } from 'vs/editor/common/languages/languageConfiguration';
|
||||
import { OnEnterSupport } from 'vs/editor/common/languages/supports/onEnter';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/javascriptOnEnterRules';
|
||||
import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/onEnterRules';
|
||||
import { EditorAutoIndentStrategy } from 'vs/editor/common/config/editorOptions';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
|
||||
|
|
|
@ -59,3 +59,58 @@ export const javascriptOnEnterRules = [
|
|||
action: { indentAction: IndentAction.IndentOutdent, appendText: '\t' }
|
||||
},
|
||||
];
|
||||
|
||||
export const phpOnEnterRules = [
|
||||
{
|
||||
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
|
||||
afterText: /^\s*\*\/$/,
|
||||
action: {
|
||||
indentAction: IndentAction.IndentOutdent,
|
||||
appendText: ' * ',
|
||||
}
|
||||
},
|
||||
{
|
||||
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
|
||||
action: {
|
||||
indentAction: IndentAction.None,
|
||||
appendText: ' * ',
|
||||
}
|
||||
},
|
||||
{
|
||||
beforeText: /^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
|
||||
action: {
|
||||
indentAction: IndentAction.None,
|
||||
appendText: '* ',
|
||||
}
|
||||
},
|
||||
{
|
||||
beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
|
||||
action: {
|
||||
indentAction: IndentAction.None,
|
||||
removeText: 1,
|
||||
}
|
||||
},
|
||||
{
|
||||
beforeText: /^(\t|(\ \ ))*\ \*[^/]*\*\/\s*$/,
|
||||
action: {
|
||||
indentAction: IndentAction.None,
|
||||
removeText: 1,
|
||||
}
|
||||
},
|
||||
{
|
||||
beforeText: /^\s+([^{i\s]|i(?!f\b))/,
|
||||
previousLineText: /^\s*(((else ?)?if|for(each)?|while)\s*\(.*\)\s*|else\s*)$/,
|
||||
action: {
|
||||
indentAction: IndentAction.Outdent
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
/** Note
|
||||
export enum IndentAction {
|
||||
None = 0,
|
||||
Indent = 1,
|
||||
IndentOutdent = 2,
|
||||
Outdent = 3
|
||||
}
|
||||
*/
|
Loading…
Reference in a new issue