link.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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} {rel} {target}>Link</a>",
  68. href = r#"href="/test""#,
  69. default = r#"dioxus-prevent-default="onclick""#,
  70. class = r#"class="""#,
  71. rel = r#"rel="""#,
  72. target = r#"target="""#
  73. );
  74. assert_eq!(prepare::<Route>(), expected);
  75. }
  76. #[test]
  77. fn href_external() {
  78. #[derive(Routable, Clone)]
  79. enum Route {
  80. #[route("/")]
  81. Root {},
  82. #[route("/test")]
  83. Test {},
  84. }
  85. #[component]
  86. fn Test() -> Element {
  87. todo!()
  88. }
  89. #[component]
  90. fn Root() -> Element {
  91. rsx! {
  92. Link {
  93. to: "https://dioxuslabs.com/",
  94. "Link"
  95. }
  96. }
  97. }
  98. let expected = format!(
  99. "<h1>App</h1><a {href} {default} {class} {rel} {target}>Link</a>",
  100. href = r#"href="https://dioxuslabs.com/""#,
  101. default = r#"dioxus-prevent-default="""#,
  102. class = r#"class="""#,
  103. rel = r#"rel="noopener noreferrer""#,
  104. target = r#"target="""#
  105. );
  106. assert_eq!(prepare::<Route>(), expected);
  107. }
  108. #[test]
  109. fn with_class() {
  110. #[derive(Routable, Clone)]
  111. enum Route {
  112. #[route("/")]
  113. Root {},
  114. #[route("/test")]
  115. Test {},
  116. }
  117. #[component]
  118. fn Test() -> Element {
  119. todo!()
  120. }
  121. #[component]
  122. fn Root() -> Element {
  123. rsx! {
  124. Link {
  125. to: Route::Test {},
  126. class: "test_class",
  127. "Link"
  128. }
  129. }
  130. }
  131. let expected = format!(
  132. "<h1>App</h1><a {href} {default} {class} {rel} {target}>Link</a>",
  133. href = r#"href="/test""#,
  134. default = r#"dioxus-prevent-default="onclick""#,
  135. class = r#"class="test_class""#,
  136. rel = r#"rel="""#,
  137. target = r#"target="""#
  138. );
  139. assert_eq!(prepare::<Route>(), expected);
  140. }
  141. #[test]
  142. fn with_active_class_active() {
  143. #[derive(Routable, Clone)]
  144. enum Route {
  145. #[route("/")]
  146. Root {},
  147. }
  148. #[component]
  149. fn Root() -> Element {
  150. rsx! {
  151. Link {
  152. to: Route::Root {},
  153. active_class: "active_class".to_string(),
  154. class: "test_class",
  155. "Link"
  156. }
  157. }
  158. }
  159. let expected = format!(
  160. "<h1>App</h1><a {href} {default} {class} {rel} {target}>Link</a>",
  161. href = r#"href="/""#,
  162. default = r#"dioxus-prevent-default="onclick""#,
  163. class = r#"class="test_class active_class""#,
  164. rel = r#"rel="""#,
  165. target = r#"target="""#
  166. );
  167. assert_eq!(prepare::<Route>(), expected);
  168. }
  169. #[test]
  170. fn with_active_class_inactive() {
  171. #[derive(Routable, Clone)]
  172. enum Route {
  173. #[route("/")]
  174. Root {},
  175. #[route("/test")]
  176. Test {},
  177. }
  178. #[component]
  179. fn Test() -> Element {
  180. todo!()
  181. }
  182. #[component]
  183. fn Root() -> Element {
  184. rsx! {
  185. Link {
  186. to: Route::Test {},
  187. active_class: "active_class".to_string(),
  188. class: "test_class",
  189. "Link"
  190. }
  191. }
  192. }
  193. let expected = format!(
  194. "<h1>App</h1><a {href} {default} {class} {rel} {target}>Link</a>",
  195. href = r#"href="/test""#,
  196. default = r#"dioxus-prevent-default="onclick""#,
  197. class = r#"class="test_class""#,
  198. rel = r#"rel="""#,
  199. target = r#"target="""#
  200. );
  201. assert_eq!(prepare::<Route>(), expected);
  202. }
  203. #[test]
  204. fn with_id() {
  205. #[derive(Routable, Clone)]
  206. enum Route {
  207. #[route("/")]
  208. Root {},
  209. #[route("/test")]
  210. Test {},
  211. }
  212. #[component]
  213. fn Test() -> Element {
  214. todo!()
  215. }
  216. #[component]
  217. fn Root() -> Element {
  218. rsx! {
  219. Link {
  220. to: Route::Test {},
  221. id: "test_id",
  222. "Link"
  223. }
  224. }
  225. }
  226. let expected = format!(
  227. "<h1>App</h1><a {href} {default} {class} {rel} {target} {id}>Link</a>",
  228. href = r#"href="/test""#,
  229. default = r#"dioxus-prevent-default="onclick""#,
  230. class = r#"class="""#,
  231. id = r#"id="test_id""#,
  232. rel = r#"rel="""#,
  233. target = r#"target="""#
  234. );
  235. assert_eq!(prepare::<Route>(), expected);
  236. }
  237. #[test]
  238. fn with_new_tab() {
  239. #[derive(Routable, Clone)]
  240. enum Route {
  241. #[route("/")]
  242. Root {},
  243. #[route("/test")]
  244. Test {},
  245. }
  246. #[component]
  247. fn Test() -> Element {
  248. todo!()
  249. }
  250. #[component]
  251. fn Root() -> Element {
  252. rsx! {
  253. Link {
  254. to: Route::Test {},
  255. new_tab: true,
  256. "Link"
  257. }
  258. }
  259. }
  260. let expected = format!(
  261. "<h1>App</h1><a {href} {default} {class} {rel} {target}>Link</a>",
  262. href = r#"href="/test""#,
  263. default = r#"dioxus-prevent-default="""#,
  264. class = r#"class="""#,
  265. rel = r#"rel="""#,
  266. target = r#"target="_blank""#
  267. );
  268. assert_eq!(prepare::<Route>(), expected);
  269. }
  270. #[test]
  271. fn with_new_tab_external() {
  272. #[derive(Routable, Clone)]
  273. enum Route {
  274. #[route("/")]
  275. Root {},
  276. }
  277. #[component]
  278. fn Root() -> Element {
  279. rsx! {
  280. Link {
  281. to: "https://dioxuslabs.com/",
  282. new_tab: true,
  283. "Link"
  284. }
  285. }
  286. }
  287. let expected = format!(
  288. "<h1>App</h1><a {href} {default} {class} {rel} {target}>Link</a>",
  289. href = r#"href="https://dioxuslabs.com/""#,
  290. default = r#"dioxus-prevent-default="""#,
  291. class = r#"class="""#,
  292. rel = r#"rel="noopener noreferrer""#,
  293. target = r#"target="_blank""#
  294. );
  295. assert_eq!(prepare::<Route>(), expected);
  296. }
  297. #[test]
  298. fn with_rel() {
  299. #[derive(Routable, Clone)]
  300. enum Route {
  301. #[route("/")]
  302. Root {},
  303. #[route("/test")]
  304. Test {},
  305. }
  306. #[component]
  307. fn Test() -> Element {
  308. todo!()
  309. }
  310. #[component]
  311. fn Root() -> Element {
  312. rsx! {
  313. Link {
  314. to: Route::Test {},
  315. rel: "test_rel".to_string(),
  316. "Link"
  317. }
  318. }
  319. }
  320. let expected = format!(
  321. "<h1>App</h1><a {href} {default} {class} {rel} {target}>Link</a>",
  322. href = r#"href="/test""#,
  323. default = r#"dioxus-prevent-default="onclick""#,
  324. class = r#"class="""#,
  325. rel = r#"rel="test_rel""#,
  326. target = r#"target="""#
  327. );
  328. assert_eq!(prepare::<Route>(), expected);
  329. }