Skip to content

Commit cac2644

Browse files
authored
Skip fourslash at runtime instead of statically (#2344)
1 parent dcebe53 commit cac2644

File tree

3,110 files changed

+3171
-3126
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,110 files changed

+3171
-3126
lines changed

internal/fourslash/_scripts/convertFourslash.mts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,12 @@ const stradaFourslashPath = path.resolve(import.meta.dirname, "../", "../", "../
99

1010
let inputFileSet: Set<string> | undefined;
1111

12-
const failingTestsPath = path.join(import.meta.dirname, "failingTests.txt");
1312
const manualTestsPath = path.join(import.meta.dirname, "manualTests.txt");
1413

1514
const outputDir = path.join(import.meta.dirname, "../", "tests", "gen");
1615

1716
const unparsedFiles: string[] = [];
1817

19-
function getFailingTests(): Set<string> {
20-
const failingTestsList = fs.readFileSync(failingTestsPath, "utf-8").split("\n").map(line => line.trim().substring(4)).filter(line => line.length > 0);
21-
return new Set(failingTestsList);
22-
}
23-
2418
function getManualTests(): Set<string> {
2519
if (!fs.existsSync(manualTestsPath)) {
2620
return new Set();
@@ -43,13 +37,13 @@ export function main() {
4337
fs.rmSync(outputDir, { recursive: true, force: true });
4438
fs.mkdirSync(outputDir, { recursive: true });
4539

46-
parseTypeScriptFiles(getFailingTests(), getManualTests(), stradaFourslashPath);
40+
parseTypeScriptFiles(getManualTests(), stradaFourslashPath);
4741
console.log(unparsedFiles.join("\n"));
4842
const gofmt = which.sync("go");
4943
cp.execFileSync(gofmt, ["tool", "mvdan.cc/gofumpt", "-lang=go1.25", "-w", outputDir]);
5044
}
5145

52-
function parseTypeScriptFiles(failingTests: Set<string>, manualTests: Set<string>, folder: string): void {
46+
function parseTypeScriptFiles(manualTests: Set<string>, folder: string): void {
5347
const files = fs.readdirSync(folder);
5448

5549
files.forEach(file => {
@@ -60,14 +54,14 @@ function parseTypeScriptFiles(failingTests: Set<string>, manualTests: Set<string
6054
}
6155

6256
if (stat.isDirectory()) {
63-
parseTypeScriptFiles(failingTests, manualTests, filePath);
57+
parseTypeScriptFiles(manualTests, filePath);
6458
}
6559
else if (file.endsWith(".ts") && !manualTests.has(file.slice(0, -3))) {
6660
const content = fs.readFileSync(filePath, "utf-8");
6761
const test = parseFileContent(file, content);
6862
const isServer = filePath.split(path.sep).includes("server");
6963
if (test) {
70-
const testContent = generateGoTest(failingTests, test, isServer);
64+
const testContent = generateGoTest(test, isServer);
7165
const testPath = path.join(outputDir, `${test.name}_test.go`);
7266
fs.writeFileSync(testPath, testContent, "utf-8");
7367
}
@@ -3273,7 +3267,7 @@ interface GoTest {
32733267
commands: Cmd[];
32743268
}
32753269

3276-
function generateGoTest(failingTests: Set<string>, test: GoTest, isServer: boolean): string {
3270+
function generateGoTest(test: GoTest, isServer: boolean): string {
32773271
const testName = (test.name[0].toUpperCase() + test.name.substring(1)).replaceAll("-", "_").replaceAll(/[^a-zA-Z0-9_]/g, "");
32783272
const content = test.content;
32793273
const commands = test.commands.map(cmd => generateCmd(cmd)).join("\n");
@@ -3305,8 +3299,8 @@ import (
33053299
)
33063300
33073301
func Test${testName}(t *testing.T) {
3302+
fourslash.SkipIfFailing(t)
33083303
t.Parallel()
3309-
${failingTests.has(testName) ? "t.Skip()" : ""}
33103304
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
33113305
const content = ${content}
33123306
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)

internal/fourslash/_scripts/updateFailing.mts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,24 @@ import * as cp from "child_process";
22
import * as fs from "fs";
33
import path from "path";
44
import which from "which";
5-
import { main as convertFourslash } from "./convertFourslash.mts";
65

76
const failingTestsPath = path.join(import.meta.dirname, "failingTests.txt");
87

98
function main() {
10-
const oldFailingTests = fs.readFileSync(failingTestsPath, "utf-8");
11-
fs.writeFileSync(failingTestsPath, "", "utf-8");
12-
convertFourslash();
139
const go = which.sync("go");
1410
let testOutput: string;
1511
try {
16-
testOutput = cp.execFileSync(go, ["test", "-v", "./internal/fourslash/tests/gen"], { encoding: "utf-8" });
12+
// Run tests with TSGO_FOURSLASH_IGNORE_FAILING=1 to run all tests including those in failingTests.txt
13+
testOutput = cp.execFileSync(go, ["test", "-v", "./internal/fourslash/tests/gen"], {
14+
encoding: "utf-8",
15+
env: { ...process.env, TSGO_FOURSLASH_IGNORE_FAILING: "1" },
16+
});
1717
}
1818
catch (error) {
1919
testOutput = (error as { stdout: string; }).stdout as string;
2020
}
2121
const panicRegex = /^panic/m;
2222
if (panicRegex.test(testOutput)) {
23-
fs.writeFileSync(failingTestsPath, oldFailingTests, "utf-8");
2423
throw new Error("Unrecovered panic detected in tests\n" + testOutput);
2524
}
2625
const failRegex = /--- FAIL: ([\S]+)/gm;
@@ -32,7 +31,6 @@ function main() {
3231
}
3332

3433
fs.writeFileSync(failingTestsPath, failingTests.sort((a, b) => a.localeCompare(b, "en-US")).join("\n") + "\n", "utf-8");
35-
convertFourslash();
3634
}
3735

3836
main();
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package fourslash
2+
3+
import (
4+
"bufio"
5+
"os"
6+
"path/filepath"
7+
"runtime"
8+
"strings"
9+
"sync"
10+
"testing"
11+
)
12+
13+
var failingTests = sync.OnceValue(func() map[string]struct{} {
14+
failingTestsSet := make(map[string]struct{})
15+
16+
// Get the path to failingTests.txt relative to this source file
17+
_, thisFile, _, ok := runtime.Caller(0)
18+
if !ok {
19+
return failingTestsSet
20+
}
21+
22+
failingTestsPath := filepath.Join(filepath.Dir(thisFile), "_scripts", "failingTests.txt") //nolint:forbidigo
23+
24+
file, err := os.Open(failingTestsPath) //nolint:forbidigo
25+
if err != nil {
26+
return failingTestsSet
27+
}
28+
defer file.Close() //nolint:forbidigo
29+
30+
scanner := bufio.NewScanner(file)
31+
for scanner.Scan() {
32+
line := strings.TrimSpace(scanner.Text())
33+
if line != "" {
34+
failingTestsSet[line] = struct{}{}
35+
}
36+
}
37+
return failingTestsSet
38+
})
39+
40+
// SkipIfFailing checks if the current test is in the failingTests.txt file
41+
// and skips it unless the TSGO_FOURSLASH_IGNORE_FAILING environment variable is set.
42+
// This allows tests to be marked as failing without modifying the test files themselves.
43+
func SkipIfFailing(t *testing.T) {
44+
t.Helper()
45+
46+
if os.Getenv("TSGO_FOURSLASH_IGNORE_FAILING") != "" { //nolint:forbidigo
47+
return
48+
}
49+
50+
if _, found := failingTests()[t.Name()]; found {
51+
t.Skip("Test is in failingTests.txt")
52+
}
53+
}

internal/fourslash/tests/gen/addDeclareToFunction_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
func TestAddDeclareToFunction(t *testing.T) {
11+
fourslash.SkipIfFailing(t)
1112
t.Parallel()
12-
1313
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
1414
const content = `/*1*/function parseInt(s/*2*/:string):number;`
1515
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)

internal/fourslash/tests/gen/addDeclareToModule_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
func TestAddDeclareToModule(t *testing.T) {
11+
fourslash.SkipIfFailing(t)
1112
t.Parallel()
12-
1313
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
1414
const content = `/**/module mAmbient {
1515
module m3 { }

internal/fourslash/tests/gen/addDuplicateSetter_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
func TestAddDuplicateSetter(t *testing.T) {
11+
fourslash.SkipIfFailing(t)
1112
t.Parallel()
12-
1313
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
1414
const content = `class C {
1515
set foo(value) { }

internal/fourslash/tests/gen/addFunctionAboveMultiLineLambdaExpression_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
func TestAddFunctionAboveMultiLineLambdaExpression(t *testing.T) {
11+
fourslash.SkipIfFailing(t)
1112
t.Parallel()
12-
1313
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
1414
const content = `/**/
1515
() =>

internal/fourslash/tests/gen/addFunctionInDuplicatedConstructorClassBody_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
func TestAddFunctionInDuplicatedConstructorClassBody(t *testing.T) {
11+
fourslash.SkipIfFailing(t)
1112
t.Parallel()
12-
1313
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
1414
const content = `class Foo {
1515
constructor() { }

internal/fourslash/tests/gen/addInterfaceMemberAboveClass_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
func TestAddInterfaceMemberAboveClass(t *testing.T) {
11+
fourslash.SkipIfFailing(t)
1112
t.Parallel()
12-
1313
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
1414
const content = `
1515
interface Intersection {

internal/fourslash/tests/gen/addInterfaceToNotSatisfyConstraint_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
func TestAddInterfaceToNotSatisfyConstraint(t *testing.T) {
11+
fourslash.SkipIfFailing(t)
1112
t.Parallel()
12-
1313
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
1414
const content = `interface A {
1515
a: number;

0 commit comments

Comments
 (0)