Skip to content

Unskip JS emit tests #1211

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

Merged
merged 11 commits into from
Jun 19, 2025
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
69 changes: 38 additions & 31 deletions internal/testrunner/compiler_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"testing"

"github.com/microsoft/typescript-go/internal/checker"
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/repo"
"github.com/microsoft/typescript-go/internal/testutil"
Expand Down Expand Up @@ -83,30 +82,20 @@ func (r *CompilerBaselineRunner) EnumerateTestFiles() []string {
return files
}

var deprecatedTests = []string{
// Test deprecated `importsNotUsedAsValue`
"preserveUnusedImports.ts",
"noCrashWithVerbatimModuleSyntaxAndImportsNotUsedAsValues.ts",
"verbatimModuleSyntaxCompat.ts",
"preserveValueImports_importsNotUsedAsValues.ts",
"importsNotUsedAsValues_error.ts",
}

func (r *CompilerBaselineRunner) RunTests(t *testing.T) {
r.cleanUpLocal(t)
files := r.EnumerateTestFiles()
skippedTests := map[string]string{
"mappedTypeRecursiveInference.ts": "Skipped until we have type printer with truncation limit.",
"jsFileCompilationWithoutJsExtensions.ts": "Skipped until we have proper allowJS support (and errors when not enabled.)",
"fileReferencesWithNoExtensions.ts": "Skipped until we support adding missing extensions in subtasks in fileloader.go",
"typeOnlyMerge2.ts": "Needs investigation",
"typeOnlyMerge3.ts": "Needs investigation",
"filesEmittingIntoSameOutput.ts": "Output order nondeterministic due to collision on filename during parallel emit.",
}
deprecatedTests := []string{
// Test deprecated `importsNotUsedAsValue`
"preserveUnusedImports.ts",
"noCrashWithVerbatimModuleSyntaxAndImportsNotUsedAsValues.ts",
"verbatimModuleSyntaxCompat.ts",
"preserveValueImports_importsNotUsedAsValues.ts",
"importsNotUsedAsValues_error.ts",
}

for _, filename := range files {
if msg, ok := skippedTests[tspath.GetBaseFileName(filename)]; ok {
t.Run(tspath.GetBaseFileName(filename), func(t *testing.T) { t.Skip(msg) })
continue
}
if slices.Contains(deprecatedTests, tspath.GetBaseFileName(filename)) {
continue
}
Expand Down Expand Up @@ -324,19 +313,22 @@ func newCompilerTest(
}
}

var concurrentSkippedErrorBaselines = collections.NewSetFromItems(
"circular1.ts",
"circular3.ts",
"recursiveExportAssignmentAndFindAliasedType1.ts",
"recursiveExportAssignmentAndFindAliasedType2.ts",
"recursiveExportAssignmentAndFindAliasedType3.ts",
"superInStaticMembers1.ts target=es2015",
)
var concurrentSkippedErrorBaselines = map[string]string{
"circular1.ts": "Circular error reported in an extra position.",
"circular3.ts": "Circular error reported in an extra position.",
"recursiveExportAssignmentAndFindAliasedType1.ts": "Circular error reported in an extra position.",
"recursiveExportAssignmentAndFindAliasedType2.ts": "Circular error reported in an extra position.",
"recursiveExportAssignmentAndFindAliasedType3.ts": "Circular error reported in an extra position.",
"typeOnlyMerge2.ts": "Type-only merging is not detected when files are checked on different checkers.",
"typeOnlyMerge3.ts": "Type-only merging is not detected when files are checked on different checkers.",
}

func (c *compilerTest) verifyDiagnostics(t *testing.T, suiteName string, isSubmodule bool) {
t.Run("error", func(t *testing.T) {
if !testutil.TestProgramIsSingleThreaded() && concurrentSkippedErrorBaselines.Has(c.testName) {
t.Skip("Skipping error baseline in concurrent mode")
if !testutil.TestProgramIsSingleThreaded() {
if msg, ok := concurrentSkippedErrorBaselines[c.basename]; ok {
t.Skipf("Skipping in concurrent mode: %s", msg)
}
}

defer testutil.RecoverAndFail(t, "Panic on creating error baseline for test "+c.filename)
Expand Down Expand Up @@ -368,12 +360,27 @@ func (c *compilerTest) verifyDiagnostics(t *testing.T, suiteName string, isSubmo
})
}

var skippedEmitTests = map[string]string{
"filesEmittingIntoSameOutput.ts": "Output order nondeterministic due to collision on filename during parallel emit.",
"jsFileCompilationWithJsEmitPathSameAsInput.ts": "Output order nondeterministic due to collision on filename during parallel emit.",
"grammarErrors.ts": "Output order nondeterministic due to collision on filename during parallel emit.",
"jsFileCompilationEmitBlockedCorrectly.ts": "Output order nondeterministic due to collision on filename during parallel emit.",
"jsDeclarationsReexportAliasesEsModuleInterop.ts": "cls.d.ts is missing statements when run concurrently.",
"jsFileCompilationWithoutJsExtensions.ts": "No files are emitted.",
"typeOnlyMerge2.ts": "Nondeterministic contents when run concurrently.",
"typeOnlyMerge3.ts": "Nondeterministic contents when run concurrently.",
}

func (c *compilerTest) verifyJavaScriptOutput(t *testing.T, suiteName string, isSubmodule bool) {
if !c.hasNonDtsFiles {
return
}

t.Run("output", func(t *testing.T) {
if msg, ok := skippedEmitTests[c.basename]; ok {
t.Skip(msg)
}

defer testutil.RecoverAndFail(t, "Panic on creating js output for test "+c.filename)
headerComponents := tspath.GetPathComponentsRelativeTo(repo.TestDataPath, c.filename, tspath.ComparePathsOptions{})
if isSubmodule {
Expand Down
8 changes: 2 additions & 6 deletions internal/testutil/tsbaseline/js_emit_baseline.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,13 @@ func DoJSEmitBaseline(
harnessSettings *harnessutil.HarnessOptions,
opts baseline.Options,
) {
if options.GetAllowJS() {
t.Skip("AllowJS is not supported")
return
}
if options.OutFile != "" || options.Out != "" {
t.Skip("OutFile/Out is not supported")
// Just return, no t.Skip; these options are not going to be supported so noting them is not helpful.
return
}

if !options.NoEmit.IsTrue() && !options.EmitDeclarationOnly.IsTrue() && result.JS.Size() == 0 && len(result.Diagnostics) == 0 {
panic("Expected at least one js file to be emitted or at least one error to be created.")
t.Fatal("Expected at least one js file to be emitted or at least one error to be created.")
}

// check js output
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//// [tests/cases/conformance/salsa/deepElementAccessExpressionInJS.ts] ////

//// [declarations.d.ts]
declare var module: {
exports: {
[key: string]: any;
};
}
//// [elementAccessExpressionInJS.js]
if (module[calculatePropertyName(1)]) {
}
function calculatePropertyName(index) {
// this would be some webpack index in real life
return `property${index}`;
}


//// [elementAccessExpressionInJS.js]
if (module[calculatePropertyName(1)]) {
}
function calculatePropertyName(index) {
// this would be some webpack index in real life
return `property${index}`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//// [tests/cases/conformance/typeTagForMultipleVariableDeclarations.ts] ////

//// [typeTagForMultipleVariableDeclarations.js]
/** @type {number} */
var x,y,z;
x
y
z


//// [typeTagForMultipleVariableDeclarations.js]
/** @type {number} */
var x, y, z;
x;
y;
z;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//// [tests/cases/compiler/accessorDeclarationEmitJs.ts] ////

//// [a.js]
export const t1 = {
p: 'value',
get getter() {
return 'value';
},
}

export const t2 = {
v: 'value',
set setter(v) {},
}

export const t3 = {
p: 'value',
get value() {
return 'value';
},
set value(v) {},
}




//// [a.d.ts]
export declare const t1: {
p: string;
readonly getter: string;
};
export declare const t2: {
v: string;
setter: any;
};
export declare const t3: {
p: string;
value: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--- old.accessorDeclarationEmitJs.js
+++ new.accessorDeclarationEmitJs.js
@@= skipped -24, +24 lines =@@


//// [a.d.ts]
-export namespace t1 {
- let p: string;
- const getter: string;
-}
-export namespace t2 {
- let v: string;
- let setter: any;
-}
-export namespace t3 {
- let p_1: string;
- export { p_1 as p };
- export let value: string;
-}
+export declare const t1: {
+ p: string;
+ readonly getter: string;
+};
+export declare const t2: {
+ v: string;
+ setter: any;
+};
+export declare const t3: {
+ p: string;
+ value: string;
+};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//// [tests/cases/compiler/allowJscheckJsTypeParameterNoCrash.ts] ////

//// [func.ts]
interface ComponentOptions<V> {
watch: Record<string, WatchHandler<any>>;
}
type WatchHandler<T> = (val: T) => void;
declare function extend(options: ComponentOptions<{}>): void;
export var vextend = extend;
//// [app.js]
import {vextend} from './func';
// hover on vextend
export var a = vextend({
watch: {
data1(val) {
this.data2 = 1;
},
data2(val) { },
}
});

//// [func.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.vextend = void 0;
exports.vextend = extend;
//// [app.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.a = void 0;
const func_1 = require("./func");
// hover on vextend
exports.a = (0, func_1.vextend)({
watch: {
data1(val) {
this.data2 = 1;
},
data2(val) { },
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- old.allowJscheckJsTypeParameterNoCrash.js
+++ new.allowJscheckJsTypeParameterNoCrash.js
@@= skipped -27, +27 lines =@@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.a = void 0;
-var func_1 = require("./func");
+const func_1 = require("./func");
// hover on vextend
exports.a = (0, func_1.vextend)({
watch: {
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//// [tests/cases/compiler/ambientRequireFunction.ts] ////

//// [node.d.ts]
declare function require(moduleName: string): any;

declare module "fs" {
export function readFileSync(s: string): string;
}

//// [app.js]
/// <reference path="node.d.ts"/>

const fs = require("fs");
const text = fs.readFileSync("/a/b/c");

//// [app.js]
/// <reference path="node.d.ts"/>
const fs = require("fs");
const text = fs.readFileSync("/a/b/c");
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//// [tests/cases/compiler/ambientRequireFunction.ts] ////

//// [node.d.ts]
declare function require(moduleName: string): any;

declare module "fs" {
export function readFileSync(s: string): string;
}

//// [app.js]
/// <reference path="node.d.ts"/>

const fs = require("fs");
const text = fs.readFileSync("/a/b/c");

//// [app.js]
/// <reference path="node.d.ts"/>
const fs = require("fs");
const text = fs.readFileSync("/a/b/c");
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//// [tests/cases/compiler/amdLikeInputDeclarationEmit.ts] ////

//// [typing.d.ts]
declare function define<T=unknown>(name: string, modules: string[], ready: (...modules: unknown[]) => T);
//// [BaseClass.d.ts]
declare module "deps/BaseClass" {
class BaseClass {
static extends<A>(a: A): new () => A & BaseClass;
}
export = BaseClass;
}
//// [ExtendedClass.js]
define("lib/ExtendedClass", ["deps/BaseClass"],
/**
* {typeof import("deps/BaseClass")}
* @param {typeof import("deps/BaseClass")} BaseClass
* @returns
*/
(BaseClass) => {

const ExtendedClass = BaseClass.extends({
f: function() {
return "something";
}
});

// Exports the module in a way tsc recognize class export
const module = {};
module.exports = ExtendedClass
return module.exports;
});



//// [ExtendedClass.d.ts]
export {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- old.amdLikeInputDeclarationEmit.js
+++ new.amdLikeInputDeclarationEmit.js
@@= skipped -32, +32 lines =@@


//// [ExtendedClass.d.ts]
-export = ExtendedClass;
-declare const ExtendedClass: new () => {
- f: () => "something";
-} & import("deps/BaseClass");
+export {};
Loading
Loading