mod common;
use common::*;
fn child_key(v: &simple_update_in::Value, k: &str) -> simple_update_in::Value {
v.as_object().unwrap().get(k).unwrap().clone()
}
fn child_idx(v: &simple_update_in::Value, i: usize) -> simple_update_in::Value {
v.as_array().unwrap()[i].clone()
}
#[test]
fn nested_map_shares_sibling() {
let from = obj(vec![
("odd", obj(vec![("one", n(1.0)), ("three", n(3.0))])),
("even", obj(vec![("two", n(2.0))])),
]);
let actual = run(from.clone(), &[key("odd"), key("one")], multiply(10.0));
assert!(!from.ptr_eq(&actual));
assert!(!child_key(&from, "odd").ptr_eq(&child_key(&actual, "odd")));
assert!(child_key(&from, "even").ptr_eq(&child_key(&actual, "even")));
}
#[test]
fn remove_in_nested_map_shares_sibling() {
let from = obj(vec![
("odd", obj(vec![("one", n(1.0)), ("three", n(3.0))])),
("even", obj(vec![("two", n(2.0))])),
]);
let actual = remove(from.clone(), &[key("odd"), key("three")]);
assert!(!from.ptr_eq(&actual));
assert!(child_key(&from, "even").ptr_eq(&child_key(&actual, "even")));
}
#[test]
fn nested_array_shares_sibling() {
let from = arr(vec![
n(0.0),
arr(vec![n(1.1), n(1.2)]),
arr(vec![n(2.1), n(2.2)]),
]);
let actual = run(from.clone(), &[idx(1), idx(1)], constant(n(3.0)));
assert!(!from.ptr_eq(&actual));
assert!(!child_idx(&from, 1).ptr_eq(&child_idx(&actual, 1)));
assert!(child_idx(&from, 2).ptr_eq(&child_idx(&actual, 2)));
}
#[test]
fn remove_in_nested_array_shares_sibling() {
let from = arr(vec![arr(vec![n(1.0), n(3.0)]), arr(vec![n(2.0), n(4.0)])]);
let actual = remove(from.clone(), &[idx(0), idx(1)]);
assert!(!from.ptr_eq(&actual));
assert!(child_idx(&from, 1).ptr_eq(&child_idx(&actual, 1)));
}
#[test]
fn mix_map_array_shares_sibling() {
let from = obj(vec![
("one", arr(vec![n(1.1), n(1.2), n(1.3)])),
("two", arr(vec![n(2.1), n(2.2), n(2.3)])),
]);
let actual = run(from.clone(), &[key("one"), idx(1)], multiply(10.0));
assert!(!from.ptr_eq(&actual));
assert!(!child_key(&from, "one").ptr_eq(&child_key(&actual, "one")));
assert!(child_key(&from, "two").ptr_eq(&child_key(&actual, "two")));
}
#[test]
fn mix_array_map_shares_sibling() {
let from = arr(vec![
obj(vec![("one", n(1.0)), ("three", n(3.0))]),
obj(vec![("two", n(2.0))]),
]);
let actual = run(from.clone(), &[idx(0), key("three")], multiply(10.0));
assert!(!from.ptr_eq(&actual));
assert!(!child_idx(&from, 0).ptr_eq(&child_idx(&actual, 0)));
assert!(child_idx(&from, 1).ptr_eq(&child_idx(&actual, 1)));
}
#[test]
fn expand_map_shares_existing_subtree() {
let from = obj(vec![("two", obj(vec![("three", n(2.3))]))]);
let actual = run(from.clone(), &[key("one"), key("two")], constant(n(1.2)));
assert!(!from.ptr_eq(&actual));
assert!(child_key(&from, "two").ptr_eq(&child_key(&actual, "two")));
}
#[test]
fn deep_sharing_two_levels_down() {
let cousin = obj(vec![("keep", n(99.0))]);
let from = obj(vec![
(
"a",
obj(vec![
("target", obj(vec![("leaf", n(1.0))])),
("sibling", cousin.clone()),
]),
),
("b", obj(vec![("other", n(2.0))])),
]);
let actual = run(
from.clone(),
&[key("a"), key("target"), key("leaf")],
multiply(10.0),
);
assert!(!from.ptr_eq(&actual));
assert!(child_key(&from, "b").ptr_eq(&child_key(&actual, "b")));
let from_sib = child_key(&child_key(&from, "a"), "sibling");
let actual_sib = child_key(&child_key(&actual, "a"), "sibling");
assert!(from_sib.ptr_eq(&actual_sib));
assert_eq!(
actual,
obj(vec![
(
"a",
obj(vec![
("target", obj(vec![("leaf", n(10.0))])),
("sibling", cousin),
]),
),
("b", obj(vec![("other", n(2.0))])),
]),
);
}
#[test]
fn source_is_not_mutated() {
let from = obj(vec![
("a", obj(vec![("leaf", n(1.0))])),
("b", arr(vec![n(2.0), n(3.0)])),
]);
let snapshot = obj(vec![
("a", obj(vec![("leaf", n(1.0))])),
("b", arr(vec![n(2.0), n(3.0)])),
]);
let _ = run(from.clone(), &[key("a"), key("leaf")], multiply(10.0));
assert_eq!(from, snapshot);
}