Add fourslash tests & address CR comments

This commit is contained in:
Jason Ramsay
2016-06-24 13:16:58 -07:00
parent 369253bbc4
commit 8c503207be
6 changed files with 491 additions and 16 deletions

View File

@@ -1663,24 +1663,25 @@ namespace FourSlash {
}
}
private getIndentation(fileName: string, position: number, indentStyle: ts.IndentStyle): number {
private getIndentation(fileName: string, position: number, indentStyle: ts.IndentStyle, baseIndentSize: number): number {
const formatOptions = ts.clone(this.formatCodeOptions);
formatOptions.IndentStyle = indentStyle;
formatOptions.BaseIndentSize = baseIndentSize;
return this.languageService.getIndentationAtPosition(fileName, position, formatOptions);
}
public verifyIndentationAtCurrentPosition(numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart) {
const actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition, indentStyle);
public verifyIndentationAtCurrentPosition(numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart, baseIndentSize = 0) {
const actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition, indentStyle, baseIndentSize);
const lineCol = this.getLineColStringAtPosition(this.currentCaretPosition);
if (actual !== numberOfSpaces) {
this.raiseError(`verifyIndentationAtCurrentPosition failed at ${lineCol} - expected: ${numberOfSpaces}, actual: ${actual}`);
}
}
public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart) {
const actual = this.getIndentation(fileName, position, indentStyle);
public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart, baseIndentSize = 0) {
const actual = this.getIndentation(fileName, position, indentStyle, baseIndentSize);
const lineCol = this.getLineColStringAtPosition(position);
if (actual !== numberOfSpaces) {
this.raiseError(`verifyIndentationAtPosition failed at ${lineCol} - expected: ${numberOfSpaces}, actual: ${actual}`);
@@ -2938,8 +2939,8 @@ namespace FourSlashInterface {
this.state.verifyIndentationAtCurrentPosition(numberOfSpaces);
}
public indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle = ts.IndentStyle.Smart) {
this.state.verifyIndentationAtPosition(fileName, position, numberOfSpaces, indentStyle);
public indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle = ts.IndentStyle.Smart, baseIndentSize = 0) {
this.state.verifyIndentationAtPosition(fileName, position, numberOfSpaces, indentStyle, baseIndentSize);
}
public textAtCaretIs(text: string) {

View File

@@ -396,10 +396,8 @@ namespace ts.formatting {
if (startLine !== parentStartLine || startPos === column) {
// Use the base indent size if it is greater than
// the indentation of the inherited predecessor.
if (options.BaseIndentSize > column) {
return options.BaseIndentSize;
}
return column;
const baseIndentSize = SmartIndenter.getBaseIndentation(options);
return baseIndentSize > column ? baseIndentSize : column;
}
}

View File

@@ -16,7 +16,7 @@ namespace ts.formatting {
// no indentation when the indent style is set to none,
// so we can return fast
if (options.IndentStyle === IndentStyle.None) {
return getBaseIndentation(options);
return 0;
}
const precedingToken = findPrecedingToken(position, sourceFile);
@@ -27,7 +27,7 @@ namespace ts.formatting {
// no indentation in string \regex\template literals
const precedingTokenIsLiteral = isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind);
if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && precedingToken.end > position) {
return getBaseIndentation(options);
return 0;
}
const lineAtPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
@@ -103,7 +103,7 @@ namespace ts.formatting {
return getIndentationForNodeWorker(current, currentStart, /*ignoreActualIndentationRange*/ undefined, indentationDelta, sourceFile, options);
}
function getBaseIndentation(options: EditorOptions) {
export function getBaseIndentation(options: EditorOptions) {
return options.BaseIndentSize || 0;
}

View File

@@ -0,0 +1,264 @@
/// <reference path='fourslash.ts'/>
////
/////*1*/ module classes {
/////*2*/ class Bar {
////
/////*3*/ constructor() {
/////*4*/ }
////
/////*5*/private foo: string = "";
////
/////*6*/ private f() {
/////*7*/ var a: any[] = [[1, 2], [3, 4], 5];
/////*8*/ return ((1 + 1));
/////*9*/ }
////
/////*10*/ private f2() {
/////*11*/ if (true) { } { };
/////*12*/ }
/////*13*/ }
/////*14*/ }
////
////
/////*15*/ module interfaces {
/////*16*/ interface Foo {
////
/////*17*/ x: number;
////
/////*18*/ foo(): number;
/////*19*/ }
/////*20*/ }
////
////
/////*21*/ module nestedModules {
/////*22*/ module Foo2 {
/////*23*/ function f() {
/////*24*/ }
/////*25*/ var x: number;
/////*26*/}
/////*27*/ }
////
////
/////*28*/ module Enums {
/////*29*/ enum Foo3 {
/////*30*/ val1 ,
/////*31*/ val2,
/////*32*/ }
/////*33*/ }
////
////
/////*34*/ function controlStatements() {
/////*35*/ for (var i = 0; i < 10; i++) {
/////*36*/ }
////
/////*37*/ for (var e in foo.bar) {
/////*38*/ }
////
/////*39*/with (foo.bar) {
/////*40*/ }
////
/////*41*/ while (false) {
/////*42*/ }
////
/////*43*/ do {
/////*44*/ } while (false);
////
/////*45*/ switch (foo.bar) {
/////*46*/ }
////
/////*47*/ switch (foo.bar) {
/////*48*/ case 1:
/////*49*/ break;
/////*50*/ default:
/////*51*/ break;
/////*52*/ }
/////*53*/ }
////
////
/////*54*/ function tryCatch() {
/////*55*/try {
/////*56*/}
/////*57*/catch (err) {
/////*58*/ }
/////*59*/ }
////
////
/////*60*/ function tryFinally() {
/////*61*/ try {
/////*62*/ }
/////*63*/ finally {
/////*64*/ }
/////*65*/ }
////
////
/////*66*/ function tryCatchFinally() {
/////*67*/ try {
/////*68*/ }
/////*69*/ catch (err) {
/////*70*/ }
/////*71*/ finally {
/////*72*/ }
/////*73*/ }
////
////
/////*74*/ class indentBeforeCurly
/////*75*/ {
/////*76*/ }
////
////
/////*77*/ function argumentsListIndentation(bar,
/////*78*/ blah,
/////*79*/ );
////
////
/////*80*/ function blockIndentAfterIndentedParameter1(bar,
/////*81*/ blah) {
/////*82*/ }
////
////
/////*83*/ function blockIndentAfterIndentedParameter2(bar,
/////*84*/ blah) {
/////*85*/ if (foo) {
/////*86*/ }
/////*87*/}
////
/////*88*/ var templateLiterals = `abcdefghi
/////*89*/jklmnop
/////*90*/qrstuvwxyz`;
var originalOptions = format.copyFormatOptions();
var copy = format.copyFormatOptions();
copy.BaseIndentSize = 10;
copy.IndentSize = 4;
format.setFormatOptions(copy);
format.document();
verify.currentFileContentIs(`
module classes {
class Bar {
constructor() {
}
private foo: string = "";
private f() {
var a: any[] = [[1, 2], [3, 4], 5];
return ((1 + 1));
}
private f2() {
if (true) { } { };
}
}
}
module interfaces {
interface Foo {
x: number;
foo(): number;
}
}
module nestedModules {
module Foo2 {
function f() {
}
var x: number;
}
}
module Enums {
enum Foo3 {
val1,
val2,
}
}
function controlStatements() {
for (var i = 0; i < 10; i++) {
}
for (var e in foo.bar) {
}
with (foo.bar) {
}
while (false) {
}
do {
} while (false);
switch (foo.bar) {
}
switch (foo.bar) {
case 1:
break;
default:
break;
}
}
function tryCatch() {
try {
}
catch (err) {
}
}
function tryFinally() {
try {
}
finally {
}
}
function tryCatchFinally() {
try {
}
catch (err) {
}
finally {
}
}
class indentBeforeCurly {
}
function argumentsListIndentation(bar,
blah,
);
function blockIndentAfterIndentedParameter1(bar,
blah) {
}
function blockIndentAfterIndentedParameter2(bar,
blah) {
if (foo) {
}
}
var templateLiterals = \`abcdefghi
jklmnop
qrstuvwxyz\`;`);
format.setFormatOptions(originalOptions);

View File

@@ -68,6 +68,7 @@ declare namespace FourSlashInterface {
data?: any;
}
interface EditorOptions {
BaseIndentSize?: number,
IndentSize: number;
TabSize: number;
NewLineCharacter: string;
@@ -84,7 +85,7 @@ declare namespace FourSlashInterface {
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
PlaceOpenBraceOnNewLineForFunctions: boolean;
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
[s: string]: boolean | number | string;
[s: string]: boolean | number | string | undefined;
}
interface Range {
fileName: string;
@@ -140,7 +141,7 @@ declare namespace FourSlashInterface {
assertHasRanges(ranges: Range[]): void;
caretAtMarker(markerName?: string): void;
indentationIs(numberOfSpaces: number): void;
indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle?: ts.IndentStyle): void;
indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle?: ts.IndentStyle, baseIndentSize?: number): void;
textAtCaretIs(text: string): void;
/**
* Compiles the current file and evaluates 'expr' in a context containing

View File

@@ -0,0 +1,211 @@
/// <reference path="fourslash.ts"/>
////
////{| "indent": 10 , "baseIndentSize": 10 |}
//// module classes {
////{| "indent": 14 , "baseIndentSize": 10 |}
//// class Bar {
////{| "indent": 18 , "baseIndentSize": 10 |}
////
//// constructor() {
////{| "indent": 22, "baseIndentSize": 10 |}
//// }
////
//// private foo: string = "";
////{| "indent": 18, "baseIndentSize": 10 |}
////
//// private f() {
//// var a: any[] = [[1, 2], [3, 4], 5];
////{| "indent": 22, "baseIndentSize": 10 |}
//// return ((1 + 1));
//// }
////
////{| "indent": 18, "baseIndentSize": 10 |}
//// private f2() {
//// if (true) { } { };
//// }
//// }
//// }
////
////
//// module interfaces {
////{| "indent": 14 , "baseIndentSize": 10 |}
//// interface Foo {
////{| "indent": 18 , "baseIndentSize": 10 |}
////
//// x: number;
////{| "indent": 18 , "baseIndentSize": 10 |}
////
//// foo(): number;
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
//// }
////
////
//// module nestedModules {
//// module Foo2 {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// function f() {
//// }
////{| "indent": 18 , "baseIndentSize": 10 |}
//// var x: number;
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
//// }
////
////
//// module Enums {
//// enum Foo3 {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// val1,
////{| "indent": 18 , "baseIndentSize": 10 |}
//// val2,
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////{| "indent": 14 , "baseIndentSize": 10 |}
//// }
////
////
//// function controlStatements() {
//// for (var i = 0; i < 10; i++) {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////
//// for (var e in foo.bar) {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////
//// with (foo.bar) {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////
//// while (false) {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////
//// do {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// } while (false);
////
//// switch (foo.bar) {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////
//// switch (foo.bar) {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// case 1:
////{| "indent": 22 , "baseIndentSize": 10 |}
//// break;
//// default:
////{| "indent": 22 , "baseIndentSize": 10 |}
//// break;
//// }
//// }
////
////
//// function tryCatch() {
////{| "indent": 14 , "baseIndentSize": 10 |}
//// try {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////{| "indent": 14 , "baseIndentSize": 10 |}
//// catch (err) {
////{| "indent": 18, "baseIndentSize": 10 |}
//// }
////{| "indent": 14, "baseIndentSize": 10 |}
//// }
////
////
//// function tryFinally() {
////{| "indent": 14 , "baseIndentSize": 10 |}
//// try {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////{| "indent": 14 , "baseIndentSize": 10 |}
//// finally {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////{| "indent": 14 , "baseIndentSize": 10 |}
//// }
////
////
//// function tryCatchFinally() {
////{| "indent": 14 , "baseIndentSize": 10 |}
//// try {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////{| "indent": 14 , "baseIndentSize": 10 |}
//// catch (err) {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////{| "indent": 14 , "baseIndentSize": 10 |}
//// finally {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////{| "indent": 14 , "baseIndentSize": 10 |}
//// }
////
////
//// class indentBeforeCurly
////{| "indent": 10 , "baseIndentSize": 10 |}
////{| "indent": 10 , "baseIndentSize": 10 |}
//// {
////{| "indent": 14 , "baseIndentSize": 10 |}
//// }
////{| "indent": 10 , "baseIndentSize": 10 |}
////
////
//// function argumentsListIndentation(bar,
//// blah,
//// {| "indent": 14 , "baseIndentSize": 10 |}
//// );
////
////
//// function blockIndentAfterIndentedParameter1(bar,
//// blah) {
////{| "indent": 14 , "baseIndentSize": 10 |}
//// }
////
////
//// function blockIndentAfterIndentedParameter2(bar,
//// blah) {
//// if (foo) {
////{| "indent": 18 , "baseIndentSize": 10 |}
//// }
////}
////{| "indent": 10 , "baseIndentSize": 10 |}
////
//// var templateLiterals = `abcdefghi
////{| "indent": 0 , "baseIndentSize": 10 |}
////jklmnop
////{| "indent": 0 , "baseIndentSize": 10 |}
////qrstuvwxyz`;
////{| "indent": 10 , "baseIndentSize": 10 |}
////
////
//// module changeBaseIndentSizeInSameFile {
////{| "indent": 21 , "baseIndentSize": 17 |}
//// interface Foo {
////{| "indent": 25 , "baseIndentSize": 17 |}
////
//// x: number;
////{| "indent": 25 , "baseIndentSize": 10 |}
////
//// foo(): number;
////{| "indent": 25 , "baseIndentSize": 10 |}
//// }
////{| "indent": 21 , "baseIndentSize": 10 |}
//// }
////{| "indent": 17 , "baseIndentSize": 17 |}
////
////
////// Note: Do not add more tests at the end of this file, as
////// the purpose of this test is to verify smart indent
////// works for unterminated function arguments at the end of a file.
//// function unterminatedListIndentation(a,
////{| "indent": 14 , "baseIndentSize": 10 |}
debugger;
test.markers().forEach(marker => {
verify.indentationAtPositionIs(marker.fileName, marker.position, marker.data.indent, ts.IndentStyle.Smart, marker.data.baseIndentSize);
});