Skip to content

Support JS baselines in Extract Method unit tests #18627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 47 additions & 43 deletions src/harness/unittests/extractMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ function test(x: number) {

testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, ["Select more than a single identifier."]);

testExtractMethod("extractMethod1",
testExtractMethod("extractMethod1", [Extension.Ts],
`namespace A {
let x = 1;
function foo() {
Expand All @@ -428,7 +428,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod2",
testExtractMethod("extractMethod2", [Extension.Ts],
`namespace A {
let x = 1;
function foo() {
Expand All @@ -442,7 +442,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod3",
testExtractMethod("extractMethod3", [Extension.Ts],
`namespace A {
function foo() {
}
Expand All @@ -455,7 +455,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod4",
testExtractMethod("extractMethod4", [Extension.Ts],
`namespace A {
function foo() {
}
Expand All @@ -470,7 +470,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod5",
testExtractMethod("extractMethod5", [Extension.Ts],
`namespace A {
let x = 1;
export function foo() {
Expand All @@ -486,7 +486,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod6",
testExtractMethod("extractMethod6", [Extension.Ts],
`namespace A {
let x = 1;
export function foo() {
Expand All @@ -502,7 +502,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod7",
testExtractMethod("extractMethod7", [Extension.Ts],
`namespace A {
let x = 1;
export namespace C {
Expand All @@ -520,7 +520,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod8",
testExtractMethod("extractMethod8", [Extension.Ts],
`namespace A {
let x = 1;
namespace B {
Expand All @@ -530,7 +530,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod9",
testExtractMethod("extractMethod9", [Extension.Ts],
`namespace A {
export interface I { x: number };
namespace B {
Expand All @@ -540,7 +540,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod10",
testExtractMethod("extractMethod10", [Extension.Ts],
`namespace A {
export interface I { x: number };
class C {
Expand All @@ -551,7 +551,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod11",
testExtractMethod("extractMethod11", [Extension.Ts],
`namespace A {
let y = 1;
class C {
Expand All @@ -564,7 +564,7 @@ function test(x: number) {
}
}
}`);
testExtractMethod("extractMethod12",
testExtractMethod("extractMethod12", [Extension.Ts],
`namespace A {
let y = 1;
class C {
Expand All @@ -584,7 +584,7 @@ function test(x: number) {
// In all cases, we could use type inference, rather than passing explicit type arguments.
// Note the inclusion of arrow functions to ensure that some type parameters are not from
// targetable scopes.
testExtractMethod("extractMethod13",
testExtractMethod("extractMethod13", [Extension.Ts],
`<U1a, U1b>(u1a: U1a, u1b: U1b) => {
function F1<T1a, T1b>(t1a: T1a, t1b: T1b) {
<U2a, U2b>(u2a: U2a, u2b: U2b) => {
Expand All @@ -602,61 +602,61 @@ function test(x: number) {
}`);
// This test is descriptive, rather than normative. The current implementation
// doesn't handle type parameter shadowing.
testExtractMethod("extractMethod14",
testExtractMethod("extractMethod14", [Extension.Ts],
`function F<T>(t1: T) {
function F<T>(t2: T) {
[#|t1.toString();
t2.toString();|]
}
}`);
// Confirm that the constraint is preserved.
testExtractMethod("extractMethod15",
testExtractMethod("extractMethod15", [Extension.Ts],
`function F<T>(t1: T) {
function F<U extends T[]>(t2: U) {
[#|t2.toString();|]
}
}`);
// Confirm that the contextual type of an extracted expression counts as a use.
testExtractMethod("extractMethod16",
testExtractMethod("extractMethod16", [Extension.Ts],
`function F<T>() {
const array: T[] = [#|[]|];
}`);
// Class type parameter
testExtractMethod("extractMethod17",
testExtractMethod("extractMethod17", [Extension.Ts],
`class C<T1, T2> {
M(t1: T1, t2: T2) {
[#|t1.toString()|];
}
}`);
// Method type parameter
testExtractMethod("extractMethod18",
testExtractMethod("extractMethod18", [Extension.Ts],
`class C {
M<T1, T2>(t1: T1, t2: T2) {
[#|t1.toString()|];
}
}`);
// Coupled constraints
testExtractMethod("extractMethod19",
testExtractMethod("extractMethod19", [Extension.Ts],
`function F<T, U extends T[], V extends U[]>(v: V) {
[#|v.toString()|];
}`);

testExtractMethod("extractMethod20",
testExtractMethod("extractMethod20", [Extension.Ts, Extension.Js],
`const _ = class {
a() {
[#|let a1 = { x: 1 };
return a1.x + 10;|]
}
}`);
// Write + void return
testExtractMethod("extractMethod21",
testExtractMethod("extractMethod21", [Extension.Ts, Extension.Js],
`function foo() {
let x = 10;
[#|x++;
return;|]
}`);
// Return in finally block
testExtractMethod("extractMethod22",
testExtractMethod("extractMethod22", [Extension.Ts, Extension.Js],
`function test() {
try {
}
Expand All @@ -665,7 +665,7 @@ function test(x: number) {
}
}`);
// Extraction position - namespace
testExtractMethod("extractMethod23",
testExtractMethod("extractMethod23", [Extension.Ts],
`namespace NS {
function M1() { }
function M2() {
Expand All @@ -674,7 +674,7 @@ function test(x: number) {
function M3() { }
}`);
// Extraction position - function
testExtractMethod("extractMethod24",
testExtractMethod("extractMethod24", [Extension.Ts, Extension.Js],
`function Outer() {
function M1() { }
function M2() {
Expand All @@ -683,14 +683,14 @@ function test(x: number) {
function M3() { }
}`);
// Extraction position - file
testExtractMethod("extractMethod25",
testExtractMethod("extractMethod25", [Extension.Ts, Extension.Js],
`function M1() { }
function M2() {
[#|return 1;|]
}
function M3() { }`);
// Extraction position - class without ctor
testExtractMethod("extractMethod26",
testExtractMethod("extractMethod26", [Extension.Ts, Extension.Js],
`class C {
M1() { }
M2() {
Expand All @@ -699,7 +699,7 @@ function M3() { }`);
M3() { }
}`);
// Extraction position - class with ctor in middle
testExtractMethod("extractMethod27",
testExtractMethod("extractMethod27", [Extension.Ts, Extension.Js],
`class C {
M1() { }
M2() {
Expand All @@ -709,7 +709,7 @@ function M3() { }`);
M3() { }
}`);
// Extraction position - class with ctor at end
testExtractMethod("extractMethod28",
testExtractMethod("extractMethod28", [Extension.Ts, Extension.Js],
`class C {
M1() { }
M2() {
Expand All @@ -719,7 +719,7 @@ function M3() { }`);
constructor() { }
}`);
// Shorthand property names
testExtractMethod("extractMethod29",
testExtractMethod("extractMethod29", [Extension.Ts],
`interface UnaryExpression {
kind: "Unary";
operator: string;
Expand All @@ -738,12 +738,12 @@ function parsePrimaryExpression(): any {
throw "Not implemented";
}`);
// Type parameter as declared type
testExtractMethod("extractMethod30",
testExtractMethod("extractMethod30", [Extension.Ts, Extension.Js],
`function F<T>() {
[#|let t: T;|]
}`);
// Return in nested function
testExtractMethod("extractMethod31",
testExtractMethod("extractMethod31", [Extension.Ts, Extension.Js],
`namespace N {

export const value = 1;
Expand All @@ -756,7 +756,7 @@ function parsePrimaryExpression(): any {
}
}`);
// Return in nested class
testExtractMethod("extractMethod32",
testExtractMethod("extractMethod32", [Extension.Ts, Extension.Js],
`namespace N {

export const value = 1;
Expand All @@ -770,23 +770,27 @@ function parsePrimaryExpression(): any {
}
}`);
// Selection excludes leading trivia of declaration
testExtractMethod("extractMethod33",
testExtractMethod("extractMethod33", [Extension.Ts, Extension.Js],
`function F() {
[#|function G() { }|]
}`);
});


function testExtractMethod(caption: string, text: string) {
it(caption, () => {
Harness.Baseline.runBaseline(`extractMethod/${caption}.ts`, () => {
const t = extractTest(text);
const selectionRange = t.ranges.get("selection");
if (!selectionRange) {
throw new Error(`Test ${caption} does not specify selection range`);
}
function testExtractMethod(caption: string, extensions: Extension[], text: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make extension default to .ts?

const t = extractTest(text);
const selectionRange = t.ranges.get("selection");
if (!selectionRange) {
throw new Error(`Test ${caption} does not specify selection range`);
}

extensions.forEach(extension =>
it(`${caption} [${extension}]`, () => runBaseline(extension)));

function runBaseline(extension: Extension) {
Harness.Baseline.runBaseline(`extractMethod/${caption}${extension}`, () => {
const f = {
path: "/a.ts",
path: "/a" + extension,
content: t.source
};
const host = projectSystem.createServerHost([f, projectSystem.libFile]);
Expand Down Expand Up @@ -818,6 +822,6 @@ function parsePrimaryExpression(): any {
}
return data.join(newLineCharacter);
});
});
}
}
}
28 changes: 28 additions & 0 deletions tests/baselines/reference/extractMethod/extractMethod20.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// ==ORIGINAL==
const _ = class {
a() {
let a1 = { x: 1 };
return a1.x + 10;
}
}
// ==SCOPE::method in anonymous class expression==
const _ = class {
a() {
return this./*RENAME*/newFunction();
}

newFunction() {
let a1 = { x: 1 };
return a1.x + 10;
}
}
// ==SCOPE::function in global scope==
const _ = class {
a() {
return /*RENAME*/newFunction();
}
}
function newFunction() {
let a1 = { x: 1 };
return a1.x + 10;
}
26 changes: 26 additions & 0 deletions tests/baselines/reference/extractMethod/extractMethod21.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// ==ORIGINAL==
function foo() {
let x = 10;
x++;
return;
}
// ==SCOPE::inner function in function 'foo'==
function foo() {
let x = 10;
return /*RENAME*/newFunction();

function newFunction() {
x++;
return;
}
}
// ==SCOPE::function in global scope==
function foo() {
let x = 10;
x = /*RENAME*/newFunction(x);
return;
}
function newFunction(x) {
x++;
return x;
}
Loading