link.rs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. use dioxus::prelude::*;
  2. use dioxus_router::prelude::*;
  3. use std::str::FromStr;
  4. fn prepare<R: Routable>() -> String
  5. where
  6. <R as FromStr>::Err: std::fmt::Display,
  7. {
  8. let mut vdom = VirtualDom::new_with_props(
  9. App,
  10. AppProps::<R> {
  11. phantom: std::marker::PhantomData,
  12. },
  13. );
  14. vdom.rebuild_in_place();
  15. return dioxus_ssr::render(&vdom);
  16. #[derive(Props)]
  17. struct AppProps<R: Routable> {
  18. phantom: std::marker::PhantomData<R>,
  19. }
  20. impl<R: Routable> Clone for AppProps<R> {
  21. fn clone(&self) -> Self {
  22. Self {
  23. phantom: std::marker::PhantomData,
  24. }
  25. }
  26. }
  27. impl<R: Routable> PartialEq for AppProps<R> {
  28. fn eq(&self, _other: &Self) -> bool {
  29. false
  30. }
  31. }
  32. fn App<R: Routable>(props: AppProps<R>) -> Element
  33. where
  34. <R as FromStr>::Err: std::fmt::Display,
  35. {
  36. rsx! {
  37. h1 { "App" }
  38. Router::<R> {
  39. config: || RouterConfig::default().history(MemoryHistory::default())
  40. }
  41. }
  42. }
  43. }
  44. #[test]
  45. fn href_internal() {
  46. #[derive(Routable, Clone)]
  47. enum Route {
  48. #[route("/")]
  49. Root {},
  50. #[route("/test")]
  51. Test {},
  52. }
  53. #[component]
  54. fn Test() -> Element {
  55. todo!()
  56. }
  57. #[component]
  58. fn Root() -> Element {
  59. rsx! {
  60. Link {
  61. to: Route::Test {},
  62. "Link"
  63. }
  64. }
  65. }
  66. let expected = format!(
  67. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  68. href = r#"href="/test""#,
  69. default = r#"dioxus-prevent-default="onclick""#,
  70. class = r#"class="""#,
  71. id = r#"id="""#,
  72. rel = r#"rel="""#,
  73. target = r#"target="""#
  74. );
  75. assert_eq!(prepare::<Route>(), expected);
  76. }
  77. #[test]
  78. fn href_external() {
  79. #[derive(Routable, Clone)]
  80. enum Route {
  81. #[route("/")]
  82. Root {},
  83. #[route("/test")]
  84. Test {},
  85. }
  86. #[component]
  87. fn Test() -> Element {
  88. todo!()
  89. }
  90. #[component]
  91. fn Root() -> Element {
  92. rsx! {
  93. Link {
  94. to: "https://dioxuslabs.com/",
  95. "Link"
  96. }
  97. }
  98. }
  99. let expected = format!(
  100. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  101. href = r#"href="https://dioxuslabs.com/""#,
  102. default = r#"dioxus-prevent-default="""#,
  103. class = r#"class="""#,
  104. id = r#"id="""#,
  105. rel = r#"rel="noopener noreferrer""#,
  106. target = r#"target="""#
  107. );
  108. assert_eq!(prepare::<Route>(), expected);
  109. }
  110. #[test]
  111. fn with_class() {
  112. #[derive(Routable, Clone)]
  113. enum Route {
  114. #[route("/")]
  115. Root {},
  116. #[route("/test")]
  117. Test {},
  118. }
  119. #[component]
  120. fn Test() -> Element {
  121. todo!()
  122. }
  123. #[component]
  124. fn Root() -> Element {
  125. rsx! {
  126. Link {
  127. to: Route::Test {},
  128. class: "test_class",
  129. "Link"
  130. }
  131. }
  132. }
  133. let expected = format!(
  134. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  135. href = r#"href="/test""#,
  136. default = r#"dioxus-prevent-default="onclick""#,
  137. class = r#"class="test_class""#,
  138. id = r#"id="""#,
  139. rel = r#"rel="""#,
  140. target = r#"target="""#
  141. );
  142. assert_eq!(prepare::<Route>(), expected);
  143. }
  144. #[test]
  145. fn with_active_class_active() {
  146. #[derive(Routable, Clone)]
  147. enum Route {
  148. #[route("/")]
  149. Root {},
  150. }
  151. #[component]
  152. fn Root() -> Element {
  153. rsx! {
  154. Link {
  155. to: Route::Root {},
  156. active_class: "active_class".to_string(),
  157. class: "test_class",
  158. "Link"
  159. }
  160. }
  161. }
  162. let expected = format!(
  163. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  164. href = r#"href="/""#,
  165. default = r#"dioxus-prevent-default="onclick""#,
  166. class = r#"class="test_class active_class""#,
  167. id = r#"id="""#,
  168. rel = r#"rel="""#,
  169. target = r#"target="""#
  170. );
  171. assert_eq!(prepare::<Route>(), expected);
  172. }
  173. #[test]
  174. fn with_active_class_inactive() {
  175. #[derive(Routable, Clone)]
  176. enum Route {
  177. #[route("/")]
  178. Root {},
  179. #[route("/test")]
  180. Test {},
  181. }
  182. #[component]
  183. fn Test() -> Element {
  184. todo!()
  185. }
  186. #[component]
  187. fn Root() -> Element {
  188. rsx! {
  189. Link {
  190. to: Route::Test {},
  191. active_class: "active_class".to_string(),
  192. class: "test_class",
  193. "Link"
  194. }
  195. }
  196. }
  197. let expected = format!(
  198. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  199. href = r#"href="/test""#,
  200. default = r#"dioxus-prevent-default="onclick""#,
  201. class = r#"class="test_class""#,
  202. id = r#"id="""#,
  203. rel = r#"rel="""#,
  204. target = r#"target="""#
  205. );
  206. assert_eq!(prepare::<Route>(), expected);
  207. }
  208. #[test]
  209. fn with_id() {
  210. #[derive(Routable, Clone)]
  211. enum Route {
  212. #[route("/")]
  213. Root {},
  214. #[route("/test")]
  215. Test {},
  216. }
  217. #[component]
  218. fn Test() -> Element {
  219. todo!()
  220. }
  221. #[component]
  222. fn Root() -> Element {
  223. rsx! {
  224. Link {
  225. to: Route::Test {},
  226. id: "test_id",
  227. "Link"
  228. }
  229. }
  230. }
  231. let expected = format!(
  232. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  233. href = r#"href="/test""#,
  234. default = r#"dioxus-prevent-default="onclick""#,
  235. class = r#"class="""#,
  236. id = r#"id="test_id""#,
  237. rel = r#"rel="""#,
  238. target = r#"target="""#
  239. );
  240. assert_eq!(prepare::<Route>(), expected);
  241. }
  242. #[test]
  243. fn with_new_tab() {
  244. #[derive(Routable, Clone)]
  245. enum Route {
  246. #[route("/")]
  247. Root {},
  248. #[route("/test")]
  249. Test {},
  250. }
  251. #[component]
  252. fn Test() -> Element {
  253. todo!()
  254. }
  255. #[component]
  256. fn Root() -> Element {
  257. rsx! {
  258. Link {
  259. to: Route::Test {},
  260. new_tab: true,
  261. "Link"
  262. }
  263. }
  264. }
  265. let expected = format!(
  266. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  267. href = r#"href="/test""#,
  268. default = r#"dioxus-prevent-default="""#,
  269. class = r#"class="""#,
  270. id = r#"id="""#,
  271. rel = r#"rel="""#,
  272. target = r#"target="_blank""#
  273. );
  274. assert_eq!(prepare::<Route>(), expected);
  275. }
  276. #[test]
  277. fn with_new_tab_external() {
  278. #[derive(Routable, Clone)]
  279. enum Route {
  280. #[route("/")]
  281. Root {},
  282. }
  283. #[component]
  284. fn Root() -> Element {
  285. rsx! {
  286. Link {
  287. to: "https://dioxuslabs.com/",
  288. new_tab: true,
  289. "Link"
  290. }
  291. }
  292. }
  293. let expected = format!(
  294. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  295. href = r#"href="https://dioxuslabs.com/""#,
  296. default = r#"dioxus-prevent-default="""#,
  297. class = r#"class="""#,
  298. id = r#"id="""#,
  299. rel = r#"rel="noopener noreferrer""#,
  300. target = r#"target="_blank""#
  301. );
  302. assert_eq!(prepare::<Route>(), expected);
  303. }
  304. #[test]
  305. fn with_rel() {
  306. #[derive(Routable, Clone)]
  307. enum Route {
  308. #[route("/")]
  309. Root {},
  310. #[route("/test")]
  311. Test {},
  312. }
  313. #[component]
  314. fn Test() -> Element {
  315. todo!()
  316. }
  317. #[component]
  318. fn Root() -> Element {
  319. rsx! {
  320. Link {
  321. to: Route::Test {},
  322. rel: "test_rel".to_string(),
  323. "Link"
  324. }
  325. }
  326. }
  327. let expected = format!(
  328. "<h1>App</h1><a {href} {default} {class} {id} {rel} {target}>Link</a>",
  329. href = r#"href="/test""#,
  330. default = r#"dioxus-prevent-default="onclick""#,
  331. class = r#"class="""#,
  332. id = r#"id="""#,
  333. rel = r#"rel="test_rel""#,
  334. target = r#"target="""#
  335. );
  336. assert_eq!(prepare::<Route>(), expected);
  337. }