use std::rc::Rc;
use crate::{Client, transaction, get_driver};
use crate::computed::{Computed, Value, DropResource};
use crate::computed::tests::box_value_version::SubscribeValueVer;
use crate::struct_mut::{ValueMut};
#[test]
fn basic() {
let value1: Value<i32> = Value::new(1);
let value2: Value<i32> = Value::new(2);
let sum: Computed<i32> = {
let com1 = value1.to_computed();
let com2 = value2.to_computed();
Computed::from(move |context| -> i32 {
let value1 = com1.get(context);
let value2 = com2.get(context);
value1 + value2
})
};
let mut sum_value = SubscribeValueVer::new(sum);
assert_eq!(sum_value.get(), (3, 1));
value1.set(4);
assert_eq!(sum_value.get(), (6, 2));
value2.set(5);
assert_eq!(sum_value.get(), (9, 3));
sum_value.off();
value2.set(99);
assert_eq!(sum_value.get(), (9, 3));
}
#[test]
fn basic2() {
let val1 = Value::new(4);
let val2 = Value::new(5);
let com1: Computed<i32> = val1.to_computed();
let com2: Computed<i32> = val2.to_computed();
let sum = Computed::from(move |context| {
let a = com1.get(context);
let b = com2.get(context);
a + b
});
let suma2 = sum.map(|value: i32| -> i32 {
2 * (value)
});
let mut sum_box1 = SubscribeValueVer::new(sum);
let mut sum_box2 = SubscribeValueVer::new(suma2);
assert_eq!(sum_box1.get(), (9, 1));
assert_eq!(sum_box2.get(), (18, 1));
val1.set(111);
assert_eq!(sum_box1.get(), (116, 2));
assert_eq!(sum_box2.get(), (232, 2));
val2.set(888);
assert_eq!(sum_box1.get(), (999, 3));
assert_eq!(sum_box2.get(), (1998, 3));
sum_box1.off();
sum_box2.off();
val2.set(999);
assert_eq!(sum_box1.get(), (999, 3));
assert_eq!(sum_box2.get(), (1998, 3));
}
#[test]
fn pointers() {
fn foo1() -> i32 {
0
}
fn foo2() -> i32 {
0
}
fn foo3(_yy: i32) -> i32 {
0
}
let pointer1: u64 = foo1 as *const () as u64;
let pointer2: u64 = foo2 as *const () as u64;
let pointer11: u64 = foo1 as *const () as u64;
let pointer4: u64 = foo3 as *const () as u64;
assert!(pointer1 != pointer2);
assert!(pointer1 == pointer11);
assert!(pointer1 != pointer4);
}
#[test]
fn test_subscription() {
let val1 = Value::new(1);
let val2 = Value::new(2);
let val3 = Value::new(3);
let com1: Computed<i32> = val1.to_computed();
let com2: Computed<i32> = val2.to_computed();
#[allow(unused_variables)]
let com3: Computed<i32> = val3.to_computed();
let sum = Computed::from(move |context| -> i32 {
let value1 = com1.get(context);
let value2 = com2.get(context);
value1 + value2
});
let mut sum_value = SubscribeValueVer::new(sum);
assert_eq!(sum_value.get(), (3, 1));
val1.set(2);
assert_eq!(sum_value.get(), (4, 2));
val2.set(10);
assert_eq!(sum_value.get(), (12, 3));
val3.set(10);
assert_eq!(sum_value.get(), (12, 3));
val2.set(20);
assert_eq!(sum_value.get(), (22, 4));
sum_value.off();
val1.set(2);
assert_eq!(sum_value.get(), (22, 4));
val1.set(2);
assert_eq!(sum_value.get(), (22, 4));
val2.set(2);
assert_eq!(sum_value.get(), (22, 4));
val3.set(2);
assert_eq!(sum_value.get(), (22, 4));
}
#[test]
fn test_computed_cache() {
let root = get_driver().inner.dependencies.clone();
assert_eq!(root.graph.all_connections_len(), 0);
{
let a = Value::new(1);
let b = Value::new(2);
let c: Computed<u32> = {
let a = a.clone();
Computed::from(move |context| {
let a_val = a.get(context);
let b_val = b.get(context);
a_val + b_val
})
};
let d: Computed<bool> = {
let c = c.clone();
Computed::from(move |context| -> bool {
let c_value = c.get(context);
c_value % 2 == 0
})
};
let mut c = SubscribeValueVer::new(c);
let mut d = SubscribeValueVer::new(d);
assert_eq!(c.get(), (3, 1));
assert_eq!(d.get(), (false, 1));
a.set(2);
assert_eq!(c.get(), (4, 2));
assert_eq!(d.get(), (true, 2));
a.set(2);
assert_eq!(c.get(), (4, 2));
assert_eq!(d.get(), (true, 2));
a.set(4);
assert_eq!(c.get(), (6, 3));
assert_eq!(d.get(), (true, 2));
assert_eq!(root.graph.all_connections_len(), 5);
c.off();
d.off();
assert_eq!(root.graph.all_connections_len(), 0);
}
assert_eq!(root.graph.all_connections_len(), 0);
}
#[test]
fn test_computed_new_value() {
#![allow(clippy::many_single_char_names)]
let root = get_driver().inner.dependencies.clone();
let a = Value::new(0);
let b = Value::new(0);
let c = Value::new(0);
let d: Computed<u32> = {
let a = a.clone();
Computed::from(move |context| {
let a_val = a.get(context);
let b_val = b.get(context);
a_val + b_val
})
};
let e: Computed<u32> = {
let d = d.clone();
let c = c.clone();
Computed::from(move |context| -> u32 {
let d_val = d.get(context);
let c_val = c.get(context);
d_val + c_val
})
};
let mut d = SubscribeValueVer::new(d);
let mut e = SubscribeValueVer::new(e);
assert_eq!(d.get(), (0, 1));
assert_eq!(e.get(), (0, 1));
a.set(33);
assert_eq!(d.get(), (33, 2));
assert_eq!(e.get(), (33, 2));
c.set(66);
assert_eq!(d.get(), (33, 2));
assert_eq!(e.get(), (99, 3));
d.off();
e.off();
assert_eq!(root.graph.all_connections_len(), 0);
}
#[test]
fn test_computed_new_value2() {
#![allow(clippy::many_single_char_names)]
let root = get_driver().inner.dependencies.clone();
let a = Value::new(0);
let b = Value::new(0);
let d: Computed<u32> = {
let a = a.clone();
let b = b.clone();
Computed::from(move |context| a.get(context) + b.get(context))
};
let mut d = SubscribeValueVer::new(d);
assert_eq!(d.get(), (0, 1));
a.set(2);
assert_eq!(d.get(), (2, 2));
b.set(9);
assert_eq!(d.get(), (11, 3));
a.set(3);
assert_eq!(d.get(), (12, 4));
a.set(4);
assert_eq!(d.get(), (13, 5));
d.off();
assert_eq!(root.graph.all_connections_len(), 0);
}
#[test]
fn test_computed_switch_subscription() {
#[derive(Clone)]
enum Switch {
Ver1,
Ver2,
Ver3,
}
let root = get_driver().inner.dependencies.clone();
let switch = Value::new(Switch::Ver1);
let a = Value::new(0);
let b = Value::new(0);
let c = Value::new(0);
let sum: Computed<u32> = {
let switch = switch.clone();
let a = a.clone();
let b = b.clone();
let c = c.clone();
Computed::from(move |context| -> u32 {
let switch_value = switch.get(context);
match switch_value {
Switch::Ver1 => {
a.get(context)
}
Switch::Ver2 => {
let a_value = a.get(context);
let b_value = b.get(context);
a_value + b_value
}
Switch::Ver3 => {
let a_value = a.get(context);
let b_value = b.get(context);
let c_value = c.get(context);
a_value + b_value + c_value
}
}
})
};
assert_eq!(root.graph.all_connections_len(), 0);
let mut sum = SubscribeValueVer::new(sum);
assert_eq!(root.graph.all_connections_len(), 3);
assert_eq!(sum.get(), (0, 1));
assert_eq!(root.graph.all_connections_len(), 3);
a.set(1);
assert_eq!(sum.get(), (1, 2));
assert_eq!(root.graph.all_connections_len(), 3);
b.set(1);
assert_eq!(sum.get(), (1, 2));
c.set(1);
assert_eq!(sum.get(), (1, 2));
a.set(0);
b.set(0);
c.set(0);
assert_eq!(sum.get(), (0, 3));
assert_eq!(root.graph.all_connections_len(), 3);
switch.set(Switch::Ver2);
assert_eq!(root.graph.all_connections_len(), 4);
assert_eq!(sum.get(), (0, 3));
a.set(1);
assert_eq!(root.graph.all_connections_len(), 4);
assert_eq!(sum.get(), (1, 4));
b.set(1);
assert_eq!(sum.get(), (2, 5));
c.set(1);
assert_eq!(sum.get(), (2, 5));
a.set(0);
b.set(0);
c.set(0);
assert_eq!(sum.get(), (0, 7));
switch.set(Switch::Ver3);
assert_eq!(sum.get(), (0, 7));
assert_eq!(root.graph.all_connections_len(), 5);
a.set(1);
assert_eq!(sum.get(), (1, 8));
b.set(1);
assert_eq!(sum.get(), (2, 9));
c.set(1);
assert_eq!(sum.get(), (3, 10));
root.transaction(|_| {
a.set(0);
b.set(0);
c.set(0);
});
assert_eq!(sum.get(), (0, 11));
sum.off();
assert_eq!(root.graph.all_connections_len(), 0);
}
#[test]
fn test_transaction() {
let root = get_driver().inner.dependencies.clone();
assert_eq!(root.graph.all_connections_len(), 0);
let val1 = Value::new(1);
let val2 = Value::new(2);
let val3 = Computed::from({
let val1 = val1.clone();
let val2 = val2.clone();
move |context| {
val1.get(context) + val2.get(context)
}
});
let mut val2sub = SubscribeValueVer::new(val3);
assert_eq!(val2sub.get(), (3, 1));
val1.set(444);
assert_eq!(val2sub.get(), (446, 2));
root.transaction(|context| {
assert_eq!(val2sub.get(), (446, 2));
val1.set(222);
assert_eq!(val1.get(context), 444);
assert_eq!(val2sub.get(), (446, 2));
val2.set(333);
assert_eq!(val2.get(context), 2);
assert_eq!(val2sub.get(), (446, 2));
});
root.transaction(|context| {
assert_eq!(val1.get(context), 222);
assert_eq!(val2.get(context), 333);
});
assert_eq!(val2sub.get(), (555, 3));
val2sub.off();
assert_eq!(root.graph.all_connections_len(), 0);
}
#[test]
#[allow(clippy::bool_assert_comparison)]
fn test_connect() {
let is_subscribe = Rc::new(ValueMut::new(false));
let value = Value::with_connect(10, {
let is_subscribe = is_subscribe.clone();
move |_value| {
is_subscribe.set(true);
DropResource::new({
let is_subscribe = is_subscribe.clone();
move || {
is_subscribe.set(false);
}
})
}
});
assert_eq!(is_subscribe.get(), false);
let current_value = Rc::new(ValueMut::new(0));
let client = value.clone().subscribe({
let current_value = current_value.clone();
move |val| {
current_value.set(val);
}
});
assert_eq!(is_subscribe.get(), true);
drop(client);
assert_eq!(is_subscribe.get(), false);
let client = value.subscribe({
move |val| {
current_value.set(val);
}
});
assert_eq!(is_subscribe.get(), true);
drop(client);
assert_eq!(is_subscribe.get(), false);
}
#[test]
fn test_without_subscription() {
let value = Value::new(2);
let comp_2 = {
let v = value.clone();
Computed::from(move |context| v.get(context) * 2)
};
transaction(|context| {
assert_eq!(comp_2.get(context), 4);
});
value.set(6);
transaction(|context| {
assert_eq!(comp_2.get(context), 12);
});
}
#[test]
fn test_set_value_and_compare() {
let value = Value::new(2);
let value_com = value.to_computed();
let value_com = value_com.map(|item| item);
fn build(value: &Computed<i32>) -> (Rc<ValueMut<i32>>, Client) {
let boxik = Rc::new(ValueMut::new(0));
let router = Computed::from({
let value = value.clone();
move |context| {
value.get(context)
}
});
let router = Computed::from(move |context| {
router.get(context)
});
let router = router.map(|item| {
item
});
let router = router.map(|item| {
item
});
let router = router.map(|item| {
item
});
let client = router.subscribe({
let boxik = boxik.clone();
move |sub_value| {
println!("callback");
boxik.set(sub_value);
}
});
(boxik, client)
}
let (boxik, client) = build(&value_com);
let (boxik2, client2) = build(&value_com);
let (boxik3, client3) = build(&value_com);
assert_eq!(boxik.get(), 2);
value.set(3);
assert_eq!(boxik.get(), 3);
value.set_value_and_compare(4);
assert_eq!(boxik.get(), 4);
value.set_value_and_compare(4);
assert_eq!(boxik.get(), 4);
value.set_value_and_compare(5);
assert_eq!(boxik.get(), 5);
value.set_value_and_compare(5);
assert_eq!(boxik.get(), 5);
value.set(6);
assert_eq!(boxik.get(), 6);
assert_eq!(boxik2.get(), 6);
assert_eq!(boxik3.get(), 6);
drop(client);
drop(client2);
drop(client3);
}