enum.rs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #![allow(dead_code)]
  2. use indoc::indoc;
  3. use pretty_assertions::assert_eq;
  4. use tsify::Tsify;
  5. struct Foo {
  6. a: i32,
  7. b: String,
  8. }
  9. #[test]
  10. fn test_externally_tagged_enum() {
  11. #[derive(Tsify)]
  12. enum External {
  13. Struct { x: String, y: i32 },
  14. EmptyStruct {},
  15. Tuple(i32, String),
  16. EmptyTuple(),
  17. Newtype(Foo),
  18. Unit,
  19. }
  20. let expected = indoc! {r#"
  21. export type External = { Struct: { x: string; y: number } } | { EmptyStruct: {} } | { Tuple: [number, string] } | { EmptyTuple: [] } | { Newtype: Foo } | "Unit";"#
  22. };
  23. assert_eq!(External::DECL, expected);
  24. }
  25. #[test]
  26. fn test_externally_tagged_enum_with_namespace() {
  27. #[derive(Tsify)]
  28. #[tsify(namespace)]
  29. enum External {
  30. Struct { x: String, y: i32 },
  31. EmptyStruct {},
  32. Tuple(i32, String),
  33. EmptyTuple(),
  34. Newtype(Foo),
  35. Unit,
  36. }
  37. let expected = indoc! {r#"
  38. type __ExternalFoo = Foo;
  39. declare namespace External {
  40. export type Struct = { Struct: { x: string; y: number } };
  41. export type EmptyStruct = { EmptyStruct: {} };
  42. export type Tuple = { Tuple: [number, string] };
  43. export type EmptyTuple = { EmptyTuple: [] };
  44. export type Newtype = { Newtype: __ExternalFoo };
  45. export type Unit = "Unit";
  46. }
  47. export type External = { Struct: { x: string; y: number } } | { EmptyStruct: {} } | { Tuple: [number, string] } | { EmptyTuple: [] } | { Newtype: Foo } | "Unit";"#
  48. };
  49. assert_eq!(External::DECL, expected);
  50. }
  51. #[test]
  52. fn test_internally_tagged_enum() {
  53. #[derive(Tsify)]
  54. #[serde(tag = "t")]
  55. enum Internal {
  56. Struct { x: String, y: i32 },
  57. EmptyStruct {},
  58. Newtype(Foo),
  59. Unit,
  60. }
  61. let expected = indoc! {r#"
  62. export type Internal = { t: "Struct"; x: string; y: number } | { t: "EmptyStruct" } | ({ t: "Newtype" } & Foo) | { t: "Unit" };"#
  63. };
  64. assert_eq!(Internal::DECL, expected);
  65. }
  66. #[test]
  67. fn test_internally_tagged_enum_with_namespace() {
  68. #[derive(Tsify)]
  69. #[serde(tag = "t")]
  70. #[tsify(namespace)]
  71. enum Internal {
  72. Struct { x: String, y: i32 },
  73. EmptyStruct {},
  74. Newtype(Foo),
  75. Unit,
  76. }
  77. let expected = indoc! {r#"
  78. type __InternalFoo = Foo;
  79. declare namespace Internal {
  80. export type Struct = { t: "Struct"; x: string; y: number };
  81. export type EmptyStruct = { t: "EmptyStruct" };
  82. export type Newtype = { t: "Newtype" } & __InternalFoo;
  83. export type Unit = { t: "Unit" };
  84. }
  85. export type Internal = { t: "Struct"; x: string; y: number } | { t: "EmptyStruct" } | ({ t: "Newtype" } & Foo) | { t: "Unit" };"#
  86. };
  87. assert_eq!(Internal::DECL, expected);
  88. }
  89. #[test]
  90. fn test_adjacently_tagged_enum() {
  91. #[derive(Tsify)]
  92. #[serde(tag = "t", content = "c")]
  93. enum Adjacent {
  94. Struct { x: String, y: i32 },
  95. EmptyStruct {},
  96. Tuple(i32, String),
  97. EmptyTuple(),
  98. Newtype(Foo),
  99. Unit,
  100. }
  101. let expected = indoc! {r#"
  102. 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" };"#
  103. };
  104. assert_eq!(Adjacent::DECL, expected);
  105. }
  106. #[test]
  107. fn test_adjacently_tagged_enum_with_namespace() {
  108. #[derive(Tsify)]
  109. #[serde(tag = "t", content = "c")]
  110. #[tsify(namespace)]
  111. enum Adjacent {
  112. Struct { x: String, y: i32 },
  113. EmptyStruct {},
  114. Tuple(i32, String),
  115. EmptyTuple(),
  116. Newtype(Foo),
  117. Unit,
  118. }
  119. let expected = indoc! {r#"
  120. type __AdjacentFoo = Foo;
  121. declare namespace Adjacent {
  122. export type Struct = { t: "Struct"; c: { x: string; y: number } };
  123. export type EmptyStruct = { t: "EmptyStruct"; c: {} };
  124. export type Tuple = { t: "Tuple"; c: [number, string] };
  125. export type EmptyTuple = { t: "EmptyTuple"; c: [] };
  126. export type Newtype = { t: "Newtype"; c: __AdjacentFoo };
  127. export type Unit = { t: "Unit" };
  128. }
  129. 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" };"#
  130. };
  131. assert_eq!(Adjacent::DECL, expected);
  132. }
  133. #[test]
  134. fn test_untagged_enum() {
  135. #[derive(Tsify)]
  136. #[serde(untagged)]
  137. enum Untagged {
  138. Struct { x: String, y: i32 },
  139. EmptyStruct {},
  140. Tuple(i32, String),
  141. EmptyTuple(),
  142. Newtype(Foo),
  143. Unit,
  144. }
  145. let expected = if cfg!(feature = "js") {
  146. indoc! {r#"
  147. export type Untagged = { x: string; y: number } | {} | [number, string] | [] | Foo | undefined;"#
  148. }
  149. } else {
  150. indoc! {r#"
  151. export type Untagged = { x: string; y: number } | {} | [number, string] | [] | Foo | null;"#
  152. }
  153. };
  154. assert_eq!(Untagged::DECL, expected);
  155. }
  156. #[test]
  157. fn test_untagged_enum_with_namespace() {
  158. #[derive(Tsify)]
  159. #[serde(untagged)]
  160. #[tsify(namespace)]
  161. enum Untagged {
  162. Struct { x: String, y: i32 },
  163. EmptyStruct {},
  164. Tuple(i32, String),
  165. EmptyTuple(),
  166. Newtype(Foo),
  167. Unit,
  168. }
  169. let expected = if cfg!(feature = "js") {
  170. indoc! {r#"
  171. type __UntaggedFoo = Foo;
  172. declare namespace Untagged {
  173. export type Struct = { x: string; y: number };
  174. export type EmptyStruct = {};
  175. export type Tuple = [number, string];
  176. export type EmptyTuple = [];
  177. export type Newtype = __UntaggedFoo;
  178. export type Unit = undefined;
  179. }
  180. export type Untagged = { x: string; y: number } | {} | [number, string] | [] | Foo | undefined;"#
  181. }
  182. } else {
  183. indoc! {r#"
  184. type __UntaggedFoo = Foo;
  185. declare namespace Untagged {
  186. export type Struct = { x: string; y: number };
  187. export type EmptyStruct = {};
  188. export type Tuple = [number, string];
  189. export type EmptyTuple = [];
  190. export type Newtype = __UntaggedFoo;
  191. export type Unit = null;
  192. }
  193. export type Untagged = { x: string; y: number } | {} | [number, string] | [] | Foo | null;"#
  194. }
  195. };
  196. assert_eq!(Untagged::DECL, expected);
  197. }
  198. #[test]
  199. fn test_module_reimport_enum() {
  200. #[derive(Tsify)]
  201. #[tsify(namespace)]
  202. enum Internal {
  203. Struct { x: String, y: i32 },
  204. EmptyStruct {},
  205. Tuple(i32, String),
  206. EmptyTuple(),
  207. Newtype(Foo),
  208. Newtype2(Foo),
  209. Unit,
  210. }
  211. let expected = indoc! {r#"
  212. type __InternalFoo = Foo;
  213. declare namespace Internal {
  214. export type Struct = { Struct: { x: string; y: number } };
  215. export type EmptyStruct = { EmptyStruct: {} };
  216. export type Tuple = { Tuple: [number, string] };
  217. export type EmptyTuple = { EmptyTuple: [] };
  218. export type Newtype = { Newtype: __InternalFoo };
  219. export type Newtype2 = { Newtype2: __InternalFoo };
  220. export type Unit = "Unit";
  221. }
  222. export type Internal = { Struct: { x: string; y: number } } | { EmptyStruct: {} } | { Tuple: [number, string] } | { EmptyTuple: [] } | { Newtype: Foo } | { Newtype2: Foo } | "Unit";"#
  223. };
  224. assert_eq!(Internal::DECL, expected);
  225. }
  226. #[test]
  227. fn test_module_template_enum() {
  228. struct Test<T> {
  229. inner: T,
  230. }
  231. #[derive(Tsify)]
  232. #[tsify(namespace)]
  233. enum Internal<T> {
  234. Newtype(Test<T>),
  235. NewtypeF(Test<Foo>),
  236. NewtypeL(Test<Foo>),
  237. Unit,
  238. }
  239. let expected = indoc! {r#"
  240. type __InternalFoo = Foo;
  241. type __InternalTest<A> = Test<A>;
  242. declare namespace Internal {
  243. export type Newtype<T> = { Newtype: __InternalTest<T> };
  244. export type NewtypeF = { NewtypeF: __InternalTest<__InternalFoo> };
  245. export type NewtypeL = { NewtypeL: __InternalTest<__InternalFoo> };
  246. export type Unit = "Unit";
  247. }
  248. export type Internal<T> = { Newtype: Test<T> } | { NewtypeF: Test<Foo> } | { NewtypeL: Test<Foo> } | "Unit";"#
  249. };
  250. assert_eq!(expected, Internal::<Foo>::DECL);
  251. }
  252. struct Test<T> {
  253. inner: T,
  254. }
  255. #[test]
  256. fn test_module_template_enum_inner() {
  257. struct Test<T> {
  258. inner: T,
  259. }
  260. #[derive(Tsify)]
  261. #[tsify(namespace)]
  262. enum Internal {
  263. Newtype(Test<Foo>),
  264. Unit,
  265. }
  266. let expected = indoc! {r#"
  267. type __InternalFoo = Foo;
  268. type __InternalTest<A> = Test<A>;
  269. declare namespace Internal {
  270. export type Newtype = { Newtype: __InternalTest<__InternalFoo> };
  271. export type Unit = "Unit";
  272. }
  273. export type Internal = { Newtype: Test<Foo> } | "Unit";"#
  274. };
  275. assert_eq!(Internal::DECL, expected);
  276. }