#![allow(dead_code)]
use indoc::indoc;
use pretty_assertions::assert_eq;
use tsify_next::Tsify;
struct Foo {
a: i32,
b: String,
}
#[test]
fn test_externally_tagged_enum() {
#[derive(Tsify)]
enum External {
Struct { x: String, y: i32 },
EmptyStruct {},
Tuple(i32, String),
EmptyTuple(),
Newtype(Foo),
Unit,
}
let expected = indoc! {r#"
/**
* Comment for External
*/
export type External = { Struct: { x: string; y: number } } | { EmptyStruct: {} } | { Tuple: [number, string] } | { EmptyTuple: [] } | { Newtype: Foo } | "Unit";"#
};
assert_eq!(External::DECL, expected);
}
#[test]
fn test_empty_enum() {
#[derive(Tsify)]
enum Empty {}
let expected = indoc! {r#"
export type Empty = void;"#
};
assert_eq!(Empty::DECL, expected);
}
#[test]
fn test_externally_tagged_enum_with_namespace() {
#[derive(Tsify)]
#[tsify(namespace)]
enum External {
Struct { x: String, y: i32 },
EmptyStruct {},
Tuple(i32, String),
EmptyTuple(),
Newtype(Foo),
Unit,
}
let expected = indoc! {r#"
type __ExternalFoo = Foo;
/**
* Comment for External
*/
declare namespace External {
/**
* Comment for Struct
*/
export type Struct = { Struct: { x: string; y: number } };
/**
* Comment for EmptyStruct
*/
export type EmptyStruct = { EmptyStruct: {} };
/**
* Comment for Tuple
*/
export type Tuple = { Tuple: [number, string] };
/**
* Comment for EmptyTuple
*/
export type EmptyTuple = { EmptyTuple: [] };
/**
* Comment for Newtype
*/
export type Newtype = { Newtype: __ExternalFoo };
/**
* Comment for Unit
*/
export type Unit = "Unit";
}
/**
* Comment for External
*/
export type External = { Struct: { x: string; y: number } } | { EmptyStruct: {} } | { Tuple: [number, string] } | { EmptyTuple: [] } | { Newtype: Foo } | "Unit";"#
};
assert_eq!(External::DECL, expected);
}
#[test]
fn test_internally_tagged_enum() {
#[derive(Tsify)]
#[serde(tag = "t")]
enum Internal {
Struct { x: String, y: i32 },
EmptyStruct {},
Newtype(Foo),
Unit,
}
let expected = indoc! {r#"
/**
* Comment for Internal
*/
export type Internal = { t: "Struct"; x: string; y: number } | { t: "EmptyStruct" } | ({ t: "Newtype" } & Foo) | { t: "Unit" };"#
};
assert_eq!(Internal::DECL, expected);
}
#[test]
fn test_internally_tagged_enum_with_namespace() {
#[derive(Tsify)]
#[serde(tag = "t")]
#[tsify(namespace)]
enum Internal {
Struct { x: String, y: i32 },
EmptyStruct {},
Newtype(Foo),
Unit,
}
let expected = indoc! {r#"
type __InternalFoo = Foo;
/**
* Comment for Internal
*/
declare namespace Internal {
/**
* Comment for Struct
*/
export type Struct = { t: "Struct"; x: string; y: number };
/**
* Comment for EmptyStruct
*/
export type EmptyStruct = { t: "EmptyStruct" };
/**
* Comment for Newtype
*/
export type Newtype = { t: "Newtype" } & __InternalFoo;
/**
* Comment for Unit
*/
export type Unit = { t: "Unit" };
}
/**
* Comment for Internal
*/
export type Internal = { t: "Struct"; x: string; y: number } | { t: "EmptyStruct" } | ({ t: "Newtype" } & Foo) | { t: "Unit" };"#
};
assert_eq!(Internal::DECL, expected);
}
#[test]
fn test_adjacently_tagged_enum() {
#[derive(Tsify)]
#[serde(tag = "t", content = "c")]
enum Adjacent {
Struct { x: String, y: i32 },
EmptyStruct {},
Tuple(i32, String),
EmptyTuple(),
Newtype(Foo),
Unit,
}
let expected = indoc! {r#"
/**
* Comment for Adjacent
*/
export type Adjacent = { t: "Struct"; c: { x: string; y: number } } | { t: "EmptyStruct"; c: {} } | { t: "Tuple"; c: [number, string] } | { t: "EmptyTuple"; c: [] } | { t: "Newtype"; c: Foo } | { t: "Unit" };"#
};
assert_eq!(Adjacent::DECL, expected);
}
#[test]
fn test_adjacently_tagged_enum_with_namespace() {
#[derive(Tsify)]
#[serde(tag = "t", content = "c")]
#[tsify(namespace)]
enum Adjacent {
Struct { x: String, y: i32 },
EmptyStruct {},
Tuple(i32, String),
EmptyTuple(),
Newtype(Foo),
Unit,
}
let expected = indoc! {r#"
type __AdjacentFoo = Foo;
/**
* Comment for Adjacent
*/
declare namespace Adjacent {
/**
* Comment for Struct
*/
export type Struct = { t: "Struct"; c: { x: string; y: number } };
/**
* Comment for EmptyStruct
*/
export type EmptyStruct = { t: "EmptyStruct"; c: {} };
/**
* Comment for Tuple
*/
export type Tuple = { t: "Tuple"; c: [number, string] };
/**
* Comment for EmptyTuple
*/
export type EmptyTuple = { t: "EmptyTuple"; c: [] };
/**
* Comment for Newtype
*/
export type Newtype = { t: "Newtype"; c: __AdjacentFoo };
/**
* Comment for Unit
*/
export type Unit = { t: "Unit" };
}
/**
* Comment for Adjacent
*/
export type Adjacent = { t: "Struct"; c: { x: string; y: number } } | { t: "EmptyStruct"; c: {} } | { t: "Tuple"; c: [number, string] } | { t: "EmptyTuple"; c: [] } | { t: "Newtype"; c: Foo } | { t: "Unit" };"#
};
assert_eq!(Adjacent::DECL, expected);
}
#[test]
fn test_untagged_enum() {
#[derive(Tsify)]
#[serde(untagged)]
enum Untagged {
Struct { x: String, y: i32 },
EmptyStruct {},
Tuple(i32, String),
EmptyTuple(),
Newtype(Foo),
Unit,
}
let expected = if cfg!(feature = "js") {
indoc! {r#"
/**
* Comment for Untagged
*/
export type Untagged = { x: string; y: number } | {} | [number, string] | [] | Foo | undefined;"#
}
} else {
indoc! {r#"
/**
* Comment for Untagged
*/
export type Untagged = { x: string; y: number } | {} | [number, string] | [] | Foo | null;"#
}
};
assert_eq!(Untagged::DECL, expected);
}
#[test]
fn test_untagged_enum_with_namespace() {
#[derive(Tsify)]
#[serde(untagged)]
#[tsify(namespace)]
enum Untagged {
Struct { x: String, y: i32 },
EmptyStruct {},
Tuple(i32, String),
EmptyTuple(),
Newtype(Foo),
Unit,
}
let expected = if cfg!(feature = "js") {
indoc! {r#"
type __UntaggedFoo = Foo;
/**
* Comment for Untagged
*/
declare namespace Untagged {
/**
* Comment for Struct
*/
export type Struct = { x: string; y: number };
/**
* Comment for EmptyStruct
*/
export type EmptyStruct = {};
/**
* Comment for Tuple
*/
export type Tuple = [number, string];
/**
* Comment for EmptyTuple
*/
export type EmptyTuple = [];
/**
* Comment for Newtype
*/
export type Newtype = __UntaggedFoo;
/**
* Comment for Unit
*/
export type Unit = undefined;
}
/**
* Comment for Untagged
*/
export type Untagged = { x: string; y: number } | {} | [number, string] | [] | Foo | undefined;"#
}
} else {
indoc! {r#"
type __UntaggedFoo = Foo;
/**
* Comment for Untagged
*/
declare namespace Untagged {
/**
* Comment for Struct
*/
export type Struct = { x: string; y: number };
/**
* Comment for EmptyStruct
*/
export type EmptyStruct = {};
/**
* Comment for Tuple
*/
export type Tuple = [number, string];
/**
* Comment for EmptyTuple
*/
export type EmptyTuple = [];
/**
* Comment for Newtype
*/
export type Newtype = __UntaggedFoo;
/**
* Comment for Unit
*/
export type Unit = null;
}
/**
* Comment for Untagged
*/
export type Untagged = { x: string; y: number } | {} | [number, string] | [] | Foo | null;"#
}
};
assert_eq!(Untagged::DECL, expected);
}
#[test]
fn test_renamed_enum() {
#[derive(Tsify)]
#[serde(rename_all_fields = "camelCase")]
enum Renamed {
First { foo_bar: String, baz_quoox: i32 },
Second { asdf_asdf: String, qwer_qwer: i32 },
}
let expected = indoc! {r#"
export type Renamed = { First: { fooBar: string; bazQuoox: number } } | { Second: { asdfAsdf: string; qwerQwer: number } };"#
};
assert_eq!(Renamed::DECL, expected);
}
#[test]
fn test_module_reimport_enum() {
#[derive(Tsify)]
#[tsify(namespace)]
enum Internal {
Struct { x: String, y: i32 },
EmptyStruct {},
Tuple(i32, String),
EmptyTuple(),
Newtype(Foo),
Newtype2(Foo),
Unit,
}
let expected = indoc! {r#"
type __InternalFoo = Foo;
/**
* Comment for Internal
*/
declare namespace Internal {
/**
* Comment for Struct
*/
export type Struct = { Struct: { x: string; y: number } };
/**
* Comment for EmptyStruct
*/
export type EmptyStruct = { EmptyStruct: {} };
/**
* Comment for Tuple
*/
export type Tuple = { Tuple: [number, string] };
/**
* Comment for EmptyTuple
*/
export type EmptyTuple = { EmptyTuple: [] };
/**
* Comment for Newtype
*/
export type Newtype = { Newtype: __InternalFoo };
/**
* Comment for Newtype2
*/
export type Newtype2 = { Newtype2: __InternalFoo };
/**
* Comment for Unit
*/
export type Unit = "Unit";
}
/**
* Comment for Internal
*/
export type Internal = { Struct: { x: string; y: number } } | { EmptyStruct: {} } | { Tuple: [number, string] } | { EmptyTuple: [] } | { Newtype: Foo } | { Newtype2: Foo } | "Unit";"#
};
assert_eq!(Internal::DECL, expected);
}
#[test]
fn test_module_template_enum() {
struct Test<T> {
inner: T,
}
#[derive(Tsify)]
#[tsify(namespace)]
enum Internal<T> {
Newtype(Test<T>),
NewtypeF(Test<Foo>),
NewtypeL(Test<Foo>),
Unit,
}
let expected = indoc! {r#"
type __InternalFoo = Foo;
type __InternalTest<A> = Test<A>;
/**
* Comment for Internal
*/
declare namespace Internal {
/**
* Comment for Newtype
*/
export type Newtype<T> = { Newtype: __InternalTest<T> };
/**
* Comment for NewtypeF
*/
export type NewtypeF = { NewtypeF: __InternalTest<__InternalFoo> };
/**
* Comment for NewtypeL
*/
export type NewtypeL = { NewtypeL: __InternalTest<__InternalFoo> };
/**
* Comment for Unit
*/
export type Unit = "Unit";
}
/**
* Comment for Internal
*/
export type Internal<T> = { Newtype: Test<T> } | { NewtypeF: Test<Foo> } | { NewtypeL: Test<Foo> } | "Unit";"#
};
assert_eq!(expected, Internal::<Foo>::DECL);
}
struct Test<T> {
inner: T,
}
#[test]
fn test_module_template_enum_inner() {
struct Test<T> {
inner: T,
}
#[derive(Tsify)]
#[tsify(namespace)]
enum Internal {
Newtype(Test<Foo>),
Unit,
}
let expected = indoc! {r#"
type __InternalFoo = Foo;
type __InternalTest<A> = Test<A>;
/**
* Comment for Internal
*/
declare namespace Internal {
/**
* Comment for Newtype
*/
export type Newtype = { Newtype: __InternalTest<__InternalFoo> };
/**
* Comment for Unit
*/
export type Unit = "Unit";
}
/**
* Comment for Internal
*/
export type Internal = { Newtype: Test<Foo> } | "Unit";"#
};
assert_eq!(Internal::DECL, expected);
}