mirror of
https://github.com/zaphar/sycamore-state.git
synced 2025-07-22 20:29:50 -04:00
Testing infrastructure and value getter
This commit is contained in:
parent
66d1307f1b
commit
f74a051bf8
@ -6,4 +6,11 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sycamore = "0.8"
|
wasm-bindgen-test = "0.3"
|
||||||
|
wasm-bindgen = "0.2.83"
|
||||||
|
|
||||||
|
[dependencies.sycamore]
|
||||||
|
version = "0.8"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
async = ["sycamore/suspense"]
|
18
src/lib.rs
18
src/lib.rs
@ -18,8 +18,8 @@ use sycamore::prelude::*;
|
|||||||
/// Trait that maps a message and an original state value to a new value.
|
/// Trait that maps a message and an original state value to a new value.
|
||||||
/// Implementors of this trait can implement all of their state management
|
/// Implementors of this trait can implement all of their state management
|
||||||
/// logic in one place.
|
/// logic in one place.
|
||||||
pub trait MessageMapper<Msg, Out> {
|
pub trait MessageMapper<Msg, Val> {
|
||||||
fn map(&self, msg: Msg, original: &ReadSignal<Out>) -> Out;
|
fn map<'ctx>(&self, cx: Scope<'ctx>, msg: Msg, original: &'ctx Signal<Val>);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides the necessary wiring for a centralized state handling
|
/// Provides the necessary wiring for a centralized state handling
|
||||||
@ -55,8 +55,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Directly handle a state message without requiring a binding.
|
/// Directly handle a state message without requiring a binding.
|
||||||
pub fn dispatch(&self, msg: Msg) {
|
pub fn dispatch(&'ctx self, cx: Scope<'ctx>, msg: Msg) {
|
||||||
self.signal.set(self.dispatcher.map(msg, self.signal))
|
self.dispatcher.map(cx, msg, self.signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides a ReadSignal handle for the contained Signal implementation.
|
/// Provides a ReadSignal handle for the contained Signal implementation.
|
||||||
@ -74,7 +74,7 @@ where
|
|||||||
) where
|
) where
|
||||||
F: Fn(Rc<Val>) -> Msg + 'ctx,
|
F: Fn(Rc<Val>) -> Msg + 'ctx,
|
||||||
{
|
{
|
||||||
create_effect(cx, move || self.dispatch(message_fn(trigger.get())));
|
create_effect(cx, move || self.dispatch(cx, message_fn(trigger.get())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper method to get a memoized value derived from the contained
|
/// Helper method to get a memoized value derived from the contained
|
||||||
@ -91,6 +91,14 @@ where
|
|||||||
{
|
{
|
||||||
create_selector(cx, move || selector_factory(self.signal))
|
create_selector(cx, move || selector_factory(self.signal))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method to get a non reactive value from the state.
|
||||||
|
pub fn get_value<F, Val>(&'ctx self, getter_factory: F) -> Val
|
||||||
|
where
|
||||||
|
F: Fn(&'ctx ReadSignal<T>) -> Val + 'ctx,
|
||||||
|
{
|
||||||
|
getter_factory(self.signal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use wasm_bindgen_test::wasm_bindgen_test;
|
||||||
|
|
||||||
|
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
UpdateOne(String),
|
UpdateOne(String),
|
||||||
@ -40,8 +43,8 @@ where
|
|||||||
pub struct StateMachine();
|
pub struct StateMachine();
|
||||||
|
|
||||||
impl MessageMapper<Msg, FakeState> for StateMachine {
|
impl MessageMapper<Msg, FakeState> for StateMachine {
|
||||||
fn map(&self, msg: Msg, original: &ReadSignal<FakeState>) -> FakeState {
|
fn map(&self, _cx: Scope, msg: Msg, original: &Signal<FakeState>) {
|
||||||
match msg {
|
let new_state = match msg {
|
||||||
Msg::UpdateOne(val) => {
|
Msg::UpdateOne(val) => {
|
||||||
let mut new_state = original.get().as_ref().clone();
|
let mut new_state = original.get().as_ref().clone();
|
||||||
new_state.value_one = val;
|
new_state.value_one = val;
|
||||||
@ -52,7 +55,8 @@ impl MessageMapper<Msg, FakeState> for StateMachine {
|
|||||||
new_state.value_two = val;
|
new_state.value_two = val;
|
||||||
new_state
|
new_state
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
original.set(new_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +69,7 @@ macro_rules! with_scope {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[wasm_bindgen_test]
|
||||||
fn test_state_effect_flow() {
|
fn test_state_effect_flow() {
|
||||||
with_scope! {cx,
|
with_scope! {cx,
|
||||||
let state = FakeState {
|
let state = FakeState {
|
||||||
@ -94,3 +98,38 @@ fn test_state_effect_flow() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn test_state_effect_flow_async() {
|
||||||
|
use sycamore::futures::spawn_local_scoped;
|
||||||
|
with_scope! {cx,
|
||||||
|
let state = FakeState {
|
||||||
|
value_one: "foo".to_owned(),
|
||||||
|
value_two: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let handler = Handler::new(cx, state, StateMachine());
|
||||||
|
|
||||||
|
create_child_scope(cx, |cx| {
|
||||||
|
let form_val = create_signal(cx, handler.read_signal().get_untracked().value_one.clone());
|
||||||
|
|
||||||
|
handler.bind_trigger(cx, form_val, |val| Msg::UpdateOne((*val).clone()));
|
||||||
|
|
||||||
|
form_val.set("bar".to_owned());
|
||||||
|
|
||||||
|
assert_eq!(handler.read_signal().get_untracked().value_one, "bar".to_owned());
|
||||||
|
|
||||||
|
create_child_scope(cx, |cx| {
|
||||||
|
let form_val = create_signal(cx, 0);
|
||||||
|
|
||||||
|
handler.bind_trigger(cx, form_val, |val| Msg::UpdateTwo(*val));
|
||||||
|
|
||||||
|
spawn_local_scoped(cx, async {
|
||||||
|
form_val.set(1);
|
||||||
|
assert_eq!(handler.read_signal().get_untracked().value_two, 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user