diff --git a/Cargo.lock b/Cargo.lock index eec7a7b..6c0d1b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -354,11 +354,17 @@ dependencies = [ "system-deps", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" -version = "1.2.48" +version = "1.2.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" +checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", "shlex", @@ -557,6 +563,18 @@ dependencies = [ "charset", ] +[[package]] +name = "continue" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f3dc39cda960e9f5594a713c0a4687f85c25f591c67862f107cb009cdd6c46" +dependencies = [ + "atomic-waker", + "logwise", + "thiserror 2.0.17", + "wasm-bindgen", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -781,7 +799,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.12", + "parking_lot_core", ] [[package]] @@ -1154,7 +1172,7 @@ dependencies = [ "generational-box", "http", "inventory", - "parking_lot 0.12.5", + "parking_lot", "serde", "serde_json", "thiserror 2.0.17", @@ -1361,7 +1379,7 @@ dependencies = [ "hyper-util", "inventory", "lru", - "parking_lot 0.12.5", + "parking_lot", "pin-project", "rustc-hash 2.1.1", "serde", @@ -1390,7 +1408,7 @@ dependencies = [ "futures-channel", "futures-util", "generational-box", - "parking_lot 0.12.5", + "parking_lot", "rustc-hash 2.1.1", "tracing", "warnings", @@ -1527,9 +1545,9 @@ dependencies = [ [[package]] name = "dlopen2" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d65cde5fb0c42a3d5882d99807698b459f5928de035fa7f547c784fb7b34219" +checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" dependencies = [ "dlopen2_derive", "libc", @@ -1539,9 +1557,9 @@ dependencies = [ [[package]] name = "dlopen2_derive" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95f4a04e1bfbfa4835a6073177aafb95ead4de0722dbb339195fdc7e0a09599b" +checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" dependencies = [ "proc-macro2", "quote", @@ -2029,7 +2047,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e658d10252a15200ca4a1c67c7180fc0baffa3f92869bbd903025daf6f70fd65" dependencies = [ - "parking_lot 0.12.5", + "parking_lot", "tracing", ] @@ -2614,9 +2632,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -2628,9 +2646,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -2693,15 +2711,6 @@ dependencies = [ "cfb", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "inventory" version = "0.3.21" @@ -2873,6 +2882,12 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "libredox" version = "0.1.10" @@ -2935,6 +2950,24 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "logwise" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08abd1c835aab3cfd8220209d8e29345cf19c4cdf759373f6e9fafac48502fc" +dependencies = [ + "logwise_proc", + "wasm-bindgen", + "web-sys", + "web-time", +] + +[[package]] +name = "logwise_proc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba61263a12347d87ece9286fab931b7f3407b06a94ab952e676b350d7054a57" + [[package]] name = "longest-increasing-subsequence" version = "0.1.0" @@ -3114,6 +3147,16 @@ dependencies = [ "unicase", ] +[[package]] +name = "minicov" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4869b6a491569605d66d3952bcdf03df789e5b536e5f0cf7758a7f08a55ae24d" +dependencies = [ + "cc", + "walkdir", +] + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -3267,6 +3310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -3412,6 +3456,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "openssl" version = "0.10.75" @@ -3470,11 +3520,11 @@ dependencies = [ "dioxus-free-icons", "fontdue", "futures-util", + "portable_async_sleep", "regex", "reqwest", "reqwest-websocket", "uuid", - "wasm-timer", "yrs", ] @@ -3530,17 +3580,6 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.5" @@ -3548,21 +3587,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", - "parking_lot_core 0.9.12", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -3573,7 +3598,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link 0.2.1", ] @@ -3761,6 +3786,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" +[[package]] +name = "portable_async_sleep" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a29f904ab621c397d940c49f0cfe02aba3db9f2042ae880e7ae760b1479dcd2c" +dependencies = [ + "continue", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", + "web-time", +] + [[package]] name = "potential_utf" version = "0.1.4" @@ -3817,7 +3857,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.23.7", + "toml_edit 0.23.9", ] [[package]] @@ -4088,15 +4128,6 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.18" @@ -4148,9 +4179,9 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.24" +version = "0.12.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" +checksum = "b6eff9328d40131d43bd911d42d79eb6a47312002a4daefc9e37f17e74a7701a" dependencies = [ "base64", "bytes", @@ -4595,9 +4626,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "siphasher" @@ -4648,9 +4679,9 @@ dependencies = [ [[package]] name = "slotmap" -version = "1.0.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" dependencies = [ "serde", "version_check", @@ -4732,7 +4763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", - "parking_lot 0.12.5", + "parking_lot", "phf_shared 0.11.3", "precomputed-hash", "serde", @@ -4888,7 +4919,7 @@ dependencies = [ "objc2-app-kit", "objc2-foundation", "once_cell", - "parking_lot 0.12.5", + "parking_lot", "raw-window-handle 0.5.2", "raw-window-handle 0.6.2", "scopeguard", @@ -5056,7 +5087,7 @@ dependencies = [ "bytes", "libc", "mio", - "parking_lot 0.12.5", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -5191,9 +5222,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.23.7" +version = "0.23.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" dependencies = [ "indexmap", "toml_datetime 0.7.3", @@ -5228,9 +5259,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags 2.10.0", "bytes", @@ -5652,28 +5683,45 @@ dependencies = [ ] [[package]] -name = "wasm-streams" -version = "0.4.2" +name = "wasm-bindgen-test" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +checksum = "25e90e66d265d3a1efc0e72a54809ab90b9c0c515915c67cdf658689d2c22c6c" dependencies = [ - "futures-util", + "async-trait", + "cast", "js-sys", + "libm", + "minicov", + "nu-ansi-term", + "num-traits", + "oorandom", + "serde", + "serde_json", "wasm-bindgen", "wasm-bindgen-futures", - "web-sys", + "wasm-bindgen-test-macro", ] [[package]] -name = "wasm-timer" -version = "0.2.5" +name = "wasm-bindgen-test-macro" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +checksum = "7150335716dce6028bead2b848e72f47b45e7b9422f64cccdc23bedca89affc1" dependencies = [ - "futures", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", "js-sys", - "parking_lot 0.11.2", - "pin-utils", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", diff --git a/client/Cargo.toml b/client/Cargo.toml index c6fb427..7c5a306 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -10,13 +10,13 @@ edition = "2021" dioxus = { version = "0.7.2", features = ["router", "fullstack"] } uuid = { version = "1.18.1", features = ["v4", "js"] } yrs = { version = "0.24" } -wasm-timer = "0.2" futures-util = "0.3.31" reqwest-websocket = "0.5.1" reqwest = "0.12.24" regex = "1.12.2" dioxus-free-icons = { version = "0.10.0", features = ["lucide"] } fontdue = "0.9.3" +portable_async_sleep = "0.1.1" [features] default = ["desktop"] diff --git a/client/src/data/connection.rs b/client/src/data/connection.rs index e0c12e9..8a66356 100644 --- a/client/src/data/connection.rs +++ b/client/src/data/connection.rs @@ -1,9 +1,9 @@ use dioxus::prelude::*; use futures_util::{select, FutureExt, SinkExt, StreamExt}; +use portable_async_sleep::async_sleep; use reqwest::Client; use reqwest_websocket::RequestBuilderExt; use std::time::Duration; -use wasm_timer::Delay; use crate::data::Graph; #[derive(Clone)] @@ -35,12 +35,12 @@ impl Connection { Ok(resp) => match resp.into_websocket().await { Ok(ws) => ws, Err(_) => { - let _ = Delay::new(Duration::from_secs(3)).await; + let _ = async_sleep(Duration::from_secs(3)).await; continue; } }, Err(_) => { - let _ = Delay::new(Duration::from_secs(3)).await; + let _ = async_sleep(Duration::from_secs(3)).await; continue; } }; @@ -77,7 +77,7 @@ impl Connection { } dbg!("Disconnected, retrying..."); - let _ = Delay::new(Duration::from_secs(3)).await; + let _ = async_sleep(Duration::from_secs(3)).await; } } }); diff --git a/client/src/data/node.rs b/client/src/data/node.rs index f83148b..6855676 100644 --- a/client/src/data/node.rs +++ b/client/src/data/node.rs @@ -115,3 +115,155 @@ impl RenderedNode { } } } + +#[cfg(test)] +mod tests { + use super::*; + use uuid::Uuid; + + fn make_node(text: &str) -> RenderedNode { + RenderedNode::new( + Uuid::new_v4(), + (100.0, 100.0), + None, + text.to_string(), + None, + None, + 0, + ) + } + + // ------------------------- + // measure_text_width + // ------------------------- + #[test] + fn test_measure_text_width_nonzero() { + let w = measure_text_width("Hello"); + assert!(w > 0.0); + } + + #[test] + fn test_measure_text_width_adds_more_for_longer_text() { + let w1 = measure_text_width("Hi"); + let w2 = measure_text_width("Hello, world!"); + assert!(w2 > w1); + } + + // ------------------------- + // width() + // ------------------------- + #[test] + fn test_width_has_minimum() { + let node = make_node("Hi"); + let w = node.width(); + + assert!(w >= 80.0, "Width should enforce minimum"); + assert!(w > 80.0, "Width should include padding"); + } + + #[test] + fn test_width_multiline_takes_longest_line() { + let node = make_node("short\nthis is a much longer line\nmid"); + let width = node.width(); + + let width_short = measure_text_width("short") + 20.0; + let width_long = measure_text_width("this is a much longer line") + 20.0; + + assert!(width >= width_long); + assert!(width > width_short); + } + + // ------------------------- + // height() + // ------------------------- + #[test] + fn test_height_single_line() { + let node = make_node("Hello"); + let h = node.height(); + + let expected_min = FONT_SIZE + TEXT_PADDING * 2.0; + assert!(h >= expected_min); + } + + #[test] + fn test_height_multiple_lines() { + let node1 = make_node("One line"); + let node2 = make_node("Line 1\nLine 2"); + + assert!(node2.height() > node1.height()); + } + + #[test] + fn test_height_handles_trailing_newline() { + let node1 = make_node("Line 1\nLine 2"); + let node2 = make_node("Line 1\nLine 2\n"); // Should count as 3 lines + + assert!(node2.height() > node1.height()); + } + + // ------------------------- + // on() + // ------------------------- + #[test] + fn test_on_center_detection() { + let node = make_node("Center test"); + let loc = node.on((100.0, 100.0)); + + assert_eq!(loc, Some(RelativeLocation::Center)); + } + + #[test] + fn test_on_outside_returns_none() { + let node = make_node("Test"); + let loc = node.on((500.0, 500.0)); + + assert_eq!(loc, None); + } + + #[test] + fn test_on_top_detection() { + let node = make_node("Test"); + let h = node.height(); + let loc = node.on((100.0, 100.0 - h / 2.0)); + + assert_eq!(loc, Some(RelativeLocation::Top)); + } + + #[test] + fn test_on_bottom_detection() { + let node = make_node("Test"); + let h = node.height(); + let loc = node.on((100.0, 100.0 + h / 2.0)); + + assert_eq!(loc, Some(RelativeLocation::Bottom)); + } + + #[test] + fn test_on_left_detection() { + let node = make_node("Test"); + let w = node.width(); + let loc = node.on((100.0 - w / 2.0, 100.0)); + + assert_eq!(loc, Some(RelativeLocation::Left)); + } + + #[test] + fn test_on_right_detection() { + let node = make_node("Test"); + let w = node.width(); + let loc = node.on((100.0 + w / 2.0, 100.0)); + + assert_eq!(loc, Some(RelativeLocation::Right)); + } + + #[test] + fn test_on_near_edge_still_detected_with_tolerance() { + let node = make_node("Test"); + let w = node.width(); + + // Slightly outside exact edge, but within tolerance + let loc = node.on((100.0 + w / 2.0 + 8.0, 100.0)); + + assert_eq!(loc, Some(RelativeLocation::Right)); + } +}