#[macro_use]
extern crate adapton;
mod engine_is_typesafe {
#[test]
#[should_panic]
fn engine_dynamic_type_error_as_editor () {
use adapton::engine::*;
manage::init_dcg();
let n = name_of_str("cell");
let _x : Art<usize> = cell(n.clone(), 1);
let _y : Art<(usize,usize)> = cell(n, (2,3));
}
#[test]
#[should_panic]
fn engine_dynamic_type_error_as_archivist () {
use adapton::macros::*;
use adapton::engine::*;
manage::init_dcg();
let t = thunk!([t]{
let t1 = thunk!([t1]{
let n = name_of_str("cell");
let _x : Art<usize> = cell(n, 1);
});
let t2 = thunk!([t2]{
let n = name_of_str("cell");
let _y : Art<(usize,usize)> = cell(n, (2,3));
});
get!(t1);
get!(t2);
});
let _ = get!(t);
}
}
mod engine_is_from_scratch_consistent {
#[test]
fn avoid_divide_by_zero () {
use adapton::macros::*;
use adapton::engine::*;
manage::init_dcg();
let num = cell!(42);
let den = cell!(2);
let den2 = den.clone(); let den3 = den.clone();
let div = thunk![ get!(num) / get!(den) ];
let check = thunk![ if get!(den2) == 0 { None } else { Some(get!(div)) } ];
assert_eq!(get!(check), Some(21));
set(&den3, 0); assert_eq!(get!(check), None);
set(&den3, 2); assert_eq!(get!(check), Some(21));
}
#[test]
fn avoid_expensive_subcomp () {
use adapton::macros::*;
use adapton::engine::*;
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
manage::init_dcg();
let flag = cell!(true); let iter = cell!(3); let inp = cell!(42);
let inp1 = inp.clone(); let inp2 = inp.clone(); let flag1 = flag.clone(); let iter1 = iter.clone();
let iter_hash = thunk!([iter_hash]{
let inp_val = get!(inp); let mut hash_state = DefaultHasher::new();
for _ in 0..get!(iter) { inp_val.hash(&mut hash_state);
};
assert!(get!(iter) < 100); hash_state.finish() });
let root = thunk!([root]{ if get!(flag) { get!(iter_hash) }
else { get!(inp1) }
});
assert!(get!(root) != get!(inp2));
set(&flag1, false);
set(&iter1, 999999999);
assert!(get!(root) == get!(inp2));
}
}
mod engine_api {
#[test]
fn force_cell () {
use adapton::macros::*;
use adapton::engine::*;
manage::init_dcg();
let a : u32 = 1234;
let b : Art<u32> = cell!(a);
let c : u32 = force(&b);
assert_eq!(a, c);
}
#[test]
fn force_map_cell () {
use adapton::macros::*;
use adapton::engine::*;
manage::init_dcg();
let a : u32 = 1234;
let b : Art<u32> = cell!(a);
let c : u64 = force_map(&b, |_,x| x as u64);
assert_eq!(a as u64, c);
}
#[test]
fn force_map_cell_project () {
use adapton::macros::*;
use adapton::engine::*;
manage::init_dcg();
let pair = (1234 as usize, 5678 as usize);
let c = cell!(pair);
let fst = force_map(&c, |_,x| x.0);
let snd = force_map(&c, |_,x| x.1);
assert_eq!(pair.0, fst);
assert_eq!(pair.1, snd);
}
#[test]
fn force_map_prunes_dirty_traversal () {
use adapton::macros::*;
use adapton::engine::*;
use adapton::reflect;
manage::init_dcg();
reflect::dcg_reflect_begin();
let c : Art<(usize,usize)> = cell(name_of_str("pair"), (1234, 5678));
let t : Art<usize> = thunk![{
let fst = force_map(&c, |_,x| x.0);
fst + 100
}];
assert_eq!(force(&t), 1334);
let _ : Art<(usize,usize)> = cell(name_of_str("pair"), (1234, 8765));
assert_eq!(force(&t), 1334);
let traces = reflect::dcg_reflect_end();
let counts = reflect::trace::trace_count(&traces, Some(1));
assert_eq!(counts.dirty.0, 0);
assert_eq!(counts.dirty.1, 0);
}
#[test]
fn force_map_thunk () {
use adapton::macros::*;
use adapton::engine::*;
manage::init_dcg();
let a : u32 = 1234;
let b : Art<u32> = thunk![a];
let c : u64 = force_map(&b, |_,x| x as u64);
assert_eq!(a as u64, c);
}
}