mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
385 lines
11 KiB
Rust
385 lines
11 KiB
Rust
//! Copy from <https://github.com/denoland/deno_graph/blob/main/src/fast_check/transform_dts.rs#L932-#L1532>
|
|
//! Make some changes to conform to the Isolated Declarations output
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use oxc_allocator::Allocator;
|
|
use oxc_codegen::CodeGenerator;
|
|
use oxc_isolated_declarations::IsolatedDeclarations;
|
|
use oxc_parser::Parser;
|
|
use oxc_span::SourceType;
|
|
|
|
fn transform_dts_test(source: &str, expected: &str) {
|
|
let allocator = Allocator::default();
|
|
let source_type = SourceType::from_path("test.ts").unwrap();
|
|
let program = Parser::new(&allocator, source, source_type).parse().program;
|
|
|
|
let ret = IsolatedDeclarations::new(&allocator).build(&program);
|
|
let actual = CodeGenerator::new().build(&ret.program).source_text;
|
|
let expected_program = Parser::new(&allocator, expected, source_type).parse().program;
|
|
let expected = CodeGenerator::new().build(&expected_program).source_text;
|
|
|
|
assert_eq!(actual.trim(), expected.trim());
|
|
}
|
|
|
|
#[test]
|
|
fn dts_function_test() {
|
|
transform_dts_test(
|
|
"export function foo(a: number): number {
|
|
return {};
|
|
}",
|
|
"export declare function foo(a: number): number;",
|
|
);
|
|
transform_dts_test(
|
|
"export function foo(a: string): number;
|
|
export function foo(a: any): number {
|
|
return {};
|
|
}",
|
|
"export declare function foo(a: string): number;",
|
|
);
|
|
transform_dts_test(
|
|
"export function foo(a = 2): number {
|
|
return 2;
|
|
}",
|
|
"export declare function foo(a?: number): number;",
|
|
);
|
|
transform_dts_test(
|
|
"export function foo(a: string = 2): number {
|
|
return 2;
|
|
}",
|
|
"export declare function foo(a?: string): number;",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_class_decl_test() {
|
|
transform_dts_test(
|
|
"export class Foo {
|
|
a: number = 2;
|
|
static b: number = 1;
|
|
#b: number = 3;
|
|
constructor(value: string) {
|
|
return 42;
|
|
}
|
|
foo(): string {
|
|
return \"abc\";
|
|
}
|
|
#bar(): number {
|
|
return 2
|
|
}
|
|
get asdf(): number {
|
|
|
|
}
|
|
set asdf(value: number) {
|
|
|
|
}
|
|
|
|
static {
|
|
|
|
}
|
|
}",
|
|
"export declare class Foo {
|
|
#private;
|
|
a: number;
|
|
static b: number;
|
|
constructor(value: string);
|
|
foo(): string;
|
|
get asdf(): number;
|
|
set asdf(value: number);
|
|
}",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_class_decl_rest_test() {
|
|
transform_dts_test(
|
|
"export class Foo {
|
|
constructor(...args: string[]) {}
|
|
}",
|
|
"export declare class Foo {
|
|
constructor(...args: string[]);
|
|
}",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_class_decl_overloads_test() {
|
|
transform_dts_test(
|
|
"export class Foo {
|
|
constructor(arg: string);
|
|
constructor(arg: number);
|
|
constructor(arg: any) {}
|
|
}",
|
|
"export declare class Foo {
|
|
constructor(arg: string);
|
|
constructor(arg: number);
|
|
}",
|
|
);
|
|
|
|
transform_dts_test(
|
|
"export class Foo {
|
|
foo(arg: string);
|
|
foo(arg: number);
|
|
foo(arg: any) {}
|
|
}",
|
|
"export declare class Foo {
|
|
foo(arg: string);
|
|
foo(arg: number);
|
|
}",
|
|
);
|
|
|
|
transform_dts_test(
|
|
"export class Foo {
|
|
constructor(arg: string);
|
|
constructor(arg: number);
|
|
constructor(arg: any) {}
|
|
|
|
bar(arg: number): number {
|
|
return 2
|
|
}
|
|
|
|
foo(arg: string);
|
|
foo(arg: number);
|
|
foo(arg: any) {}
|
|
}",
|
|
"export declare class Foo {
|
|
constructor(arg: string);
|
|
constructor(arg: number);
|
|
bar(arg: number): number;
|
|
foo(arg: string);
|
|
foo(arg: number);
|
|
}",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_class_decl_prop_test() {
|
|
transform_dts_test(
|
|
"export class Foo { declare a: string }",
|
|
"export declare class Foo {
|
|
a: string;
|
|
}",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_class_decl_prop_infer_test() {
|
|
transform_dts_test(
|
|
"export class Foo { foo = (a: string): string => ({} as any) }",
|
|
"export declare class Foo {
|
|
foo: (a: string) => string;
|
|
}",
|
|
);
|
|
transform_dts_test(
|
|
"export class Foo { foo = function(a: string): void {} }",
|
|
"export declare class Foo {
|
|
foo: (a: string) => void;
|
|
}",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_var_decl_test() {
|
|
transform_dts_test("export const foo: number = 42;", "export declare const foo: number;");
|
|
|
|
transform_dts_test("export var foo: number = 42;", "export declare var foo: number;");
|
|
|
|
transform_dts_test("export let foo: number = 42;", "export declare let foo: number;");
|
|
}
|
|
|
|
#[test]
|
|
fn dts_global_declare() {
|
|
transform_dts_test(
|
|
"declare global {
|
|
interface String {
|
|
fancyFormat(opts: StringFormatOptions): string;
|
|
}
|
|
}",
|
|
"declare global {
|
|
interface String {
|
|
fancyFormat(opts: StringFormatOptions): string;
|
|
}
|
|
}",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_inference() {
|
|
transform_dts_test(
|
|
"export const foo = null as string as number;",
|
|
"export declare const foo: number;",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_as_const() {
|
|
transform_dts_test(
|
|
"export const foo = [1, 2] as const;",
|
|
"export declare const foo: readonly [1, 2];",
|
|
);
|
|
transform_dts_test(
|
|
"export const foo = [1, ,2] as const;",
|
|
"export declare const foo: readonly [1, undefined, 2];",
|
|
);
|
|
|
|
transform_dts_test(
|
|
"export const foo = { str: \"bar\", bool: true, bool2: false, num: 42, nullish: null } as const;",
|
|
"export declare const foo: {
|
|
readonly str: \"bar\";
|
|
readonly bool: true;
|
|
readonly bool2: false;
|
|
readonly num: 42;
|
|
readonly nullish: null;
|
|
};",
|
|
);
|
|
|
|
transform_dts_test(
|
|
"export const foo = { str: [1, 2] as const } as const;",
|
|
"export declare const foo: {
|
|
readonly str: readonly [1, 2];
|
|
};",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_literal_inference_ann() {
|
|
transform_dts_test(
|
|
"export const foo: number = \"abc\";",
|
|
"export declare const foo: number;",
|
|
);
|
|
transform_dts_test("export let foo: number = \"abc\";", "export declare let foo: number;");
|
|
transform_dts_test("export var foo: number = \"abc\";", "export declare var foo: number;");
|
|
}
|
|
|
|
#[test]
|
|
fn dts_literal_inference() {
|
|
transform_dts_test("export const foo = 42;", "export declare const foo = 42;");
|
|
transform_dts_test("export const foo = \"foo\";", "export declare const foo = \"foo\";");
|
|
transform_dts_test("export const foo = true;", "export declare const foo: boolean;");
|
|
transform_dts_test("export const foo = false;", "export declare const foo: boolean;");
|
|
transform_dts_test("export const foo = null;", "export declare const foo: null;");
|
|
transform_dts_test("export let foo = undefined;", "export declare let foo: undefined;");
|
|
transform_dts_test("export let foo = 10n;", "export declare let foo: bigint;");
|
|
}
|
|
|
|
#[test]
|
|
fn dts_fn_expr() {
|
|
transform_dts_test(
|
|
"export let foo = function add(a: number, b: number): number {
|
|
return a + b;
|
|
}",
|
|
"export declare let foo: (a: number, b: number) => number;",
|
|
);
|
|
transform_dts_test(
|
|
"export let foo = function add<T>([a, b]: T): void {}",
|
|
"export declare let foo: <T>([a, b]: T) => void;",
|
|
);
|
|
transform_dts_test(
|
|
"export let foo = function add<T>({a, b}: T): void {}",
|
|
"export declare let foo: <T>({ a, b }: T) => void;",
|
|
);
|
|
transform_dts_test(
|
|
"export let foo = function add(a = 2): void {}",
|
|
"export declare let foo: (a?: number) => void;",
|
|
);
|
|
transform_dts_test(
|
|
"export let foo = function add(...params: any[]): void {}",
|
|
"export declare let foo: (...params: any[]) => void;",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_fn_arrow_expr() {
|
|
transform_dts_test(
|
|
"export let foo = (a: number, b: number): number => {
|
|
return a + b;
|
|
}",
|
|
"export declare let foo: (a: number, b: number) => number;",
|
|
);
|
|
transform_dts_test(
|
|
"export let foo = <T>([a, b]: T): void => {}",
|
|
"export declare let foo: <T>([a, b]: T) => void;",
|
|
);
|
|
transform_dts_test(
|
|
"export let foo = <T>({a, b}: T): void => {}",
|
|
"export declare let foo: <T>({ a, b }: T) => void;",
|
|
);
|
|
transform_dts_test(
|
|
"export let foo = (a = 2): void => {}",
|
|
"export declare let foo: (a?: number) => void;",
|
|
);
|
|
|
|
transform_dts_test(
|
|
"export let foo = (...params: any[]): void => {}",
|
|
"export declare let foo: (...params: any[]) => void;",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_type_export() {
|
|
transform_dts_test("interface Foo {}", "interface Foo {\n}");
|
|
transform_dts_test("type Foo = number;", "type Foo = number;");
|
|
|
|
transform_dts_test("export interface Foo {}", "export interface Foo {\n}");
|
|
transform_dts_test("export type Foo = number;", "export type Foo = number;");
|
|
}
|
|
|
|
#[test]
|
|
fn dts_enum_export() {
|
|
transform_dts_test(
|
|
"export enum Foo { A, B }",
|
|
"export declare enum Foo {\n A=0,\n B=1\n}",
|
|
);
|
|
transform_dts_test(
|
|
"export const enum Foo { A, B }",
|
|
"export declare const enum Foo {\n A=0,\n B=1\n}",
|
|
);
|
|
|
|
transform_dts_test(
|
|
"export enum Foo { A = \"foo\", B = \"bar\" }",
|
|
"export declare enum Foo {\n A = \"foo\",\n B = \"bar\"\n}",
|
|
);
|
|
|
|
// TODO: Enum rules https://www.typescriptlang.org/docs/handbook/enums.html
|
|
}
|
|
|
|
#[test]
|
|
fn dts_default_export() {
|
|
transform_dts_test(
|
|
"export default function(a: number, b: number): number {};",
|
|
"export default function(a: number, b: number): number;",
|
|
);
|
|
transform_dts_test(
|
|
"export default function(a: number, b: number): number;
|
|
export default function(a: number, b: number): any {
|
|
return foo
|
|
};",
|
|
"export default function(a: number, b: number): number;",
|
|
);
|
|
transform_dts_test(
|
|
"export default class {foo = 2};",
|
|
"export default class {\n foo: number;\n}",
|
|
);
|
|
transform_dts_test(
|
|
"export default 42;",
|
|
"declare const _default: number;\nexport default _default;",
|
|
);
|
|
transform_dts_test(
|
|
"const a: number = 42; export default a;",
|
|
"declare const a: number;\nexport default a;",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_default_export_named() {
|
|
transform_dts_test(
|
|
"export { foo, bar } from \"foo\";",
|
|
"export { foo, bar } from \"foo\";",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn dts_default_export_all() {
|
|
transform_dts_test("export * as foo from \"foo\";", "export * as foo from \"foo\";");
|
|
}
|
|
}
|