extern crate lichen;
use lichen::parse::{Parser,Block,SrcBlock,Map};
use lichen::logic::{Logic,Expect};
use lichen::var::{Var,Mut};
use lichen::source::{Src,Next};
use lichen::eval::Evaluator;
use std::collections::HashMap;
#[test]
fn parse_block() {
let src = "root\n
@root.some_item \"Thing\"\n
unequipped !root.some_item\n
@root.some_weight 4\n
has_weight root.some_weight < 5.0\n
some_comp:any [\nunequipped \nhas_weight\n]\n
\n
if unequipped \"you're looking for something?\"\n
\n
if some_comp \"welcome, \nlook around\"\n
next:now end\n
;";
let block = Parser::parse_blocks(src).expect("ERROR: Unable to parse source");
let block_ = [Block::Src(
SrcBlock {
idx: 0,
visited: false,
or_valid: false,
name: "root".to_owned(),
src: vec![Src::Mut(Mut::Swap,"root.some_item".to_owned(),vec![Var::String("Thing".to_owned())]),
Src::Logic("not_root.some_item".to_owned(),
Logic::IsNot("root.some_item".to_owned())),
Src::Logic("unequipped".to_owned(),
Logic::Is("not_root.some_item".to_owned())),
Src::Mut(Mut::Swap,"root.some_weight".to_owned(),vec![Var::Num(4.)]),
Src::Logic("has_weight".to_owned(),
Logic::LT(Var::Sym("root.some_weight".to_owned()), 5.0 .into())),
Src::Logic("some_comp".to_owned(),
Logic::Composite(
Expect::Any,
vec!["unequipped".to_owned(),"has_weight".to_owned()])),
Src::If("unequipped".to_owned(),
vec!["you're looking for something?".into()],
None),
Src::If("some_comp".to_owned(),
vec!["welcome, \nlook around".into()],
None),
Src::Next(Next::Now("end".to_owned()))],
logic: HashMap::new(),
})];
assert_eq!(block[0],block_[0]);
}
#[test]
fn parse_qsym_block() {
let src = "root\n
if !some_item \"you're looking for something?\"\n
;";
let block = Parser::parse_blocks(src).expect("ERROR: Unable to parse source");
match &block[0] {
&Block::Src(ref b) => {
let r;
match b.src[0] {
Src::Logic(ref qsym,_) => { r = qsym; },
_ => panic!("unknown source found")
}
match b.src[1] {
Src::If(ref r_,_,_) => {
assert_eq!(r,r_);
},
_ => panic!("unknown source found")
}
},
_ => panic!("unknown block found")
}
}
#[test]
fn parse_qsym_comp_block() {
let src = "root\n
has_weight some_weight < 5.0\n
some_comp:any [has_weight !some_item ]\n
;";
let block = Parser::parse_blocks(src).expect("ERROR: Unable to parse source");
match &block[0] {
&Block::Src(ref b) => {
let r;
match b.src[1] {
Src::Logic(ref qsym,_) => { r = qsym; },
_ => panic!("unknown source found")
}
match b.src[2] {
Src::Logic(ref _n,ref l) => {
match l {
&Logic::Composite(ref _x, ref v) => {
assert_eq!(r,&v[1]);
},
_ => panic!("unknown logic found")
}
},
_ => panic!("unknown source found")
}
},
_ => panic!("unknown block found")
}
}
#[test]
fn validate_qsym_block() {
let src = "root\n
@root.other_item \"thing\"\n
if root.other_item next:await store\n
;";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (_,nn) = ev.next().unwrap();
assert_eq!(nn, Some(Next::Await("store".into())));
}
#[test]
fn validate_reflection_block() {
let src = "root\n
@root.other_item \"thing\"\n
\n
hasnt !root.some_item\n
hasnt-inv !hasnt\n
comp:all root.other_item !hasnt-inv\n
if comp next:await store\n
;";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (_,nn) = ev.next().unwrap();
assert_eq!(nn, Some(Next::Await("store".into())));
}
#[test]
fn parse_if_vec_block() {
let src = "root\n
if !some_item [\n
\"you're looking for something?\"\n
\"welcome, \nlook around\"\n
next:now store]\n
;";
let block = Parser::parse_blocks(src).expect("ERROR: Unable to parse source");
match &block[0] {
&Block::Src(ref b) => {
match b.src[1] {
Src::If(_,_, ref next) => {
assert_eq!(next,&Some(Next::Now("store".to_owned())));
},
_ => panic!("unknown source found")
}
},
_ => panic!("unknown block found")
}
}
#[test]
fn parse_eval_str_block() {
let src = "root\n
@root.name \"Io\"\n
@root.weight 4\n
has_weight root.weight < 5.0\n
some_comp:all [has_weight !some_item ]\n
if some_comp \"looks like you are `root.weight kgs heavy, `root.name\"\n
;";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let ev = Evaluator::new(&mut env);
let (vars,_node) = ev.last().unwrap();
assert_eq!(vars, ["looks like you are 4 kgs heavy, Io".into()]);
}
#[test]
fn parse_compare_env_block() {
let src = "root\n
weight 0 < 1\n
if weight next:now store\n
;";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let ev = Evaluator::new(&mut env);
let (_vars,node) = ev.last().unwrap();
assert_eq!(node, Some(Next::Now("store".to_string())));
}
#[test]
fn parse_return_varkind() {
let src = "root\n
@root.name \"Io\"\n
@root.some_weight 4\n
@root.other_weight 5\n
has_weight root.some_weight < root.other_weight\n
if has_weight root.some_weight \"hi `root.name\"\n
;";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let ev = Evaluator::new(&mut env);
let (vars,_) = ev.last().unwrap();
assert_eq!(vars[0], 4.0 .into());
assert_eq!(vars[1], "hi Io" .into());
}
#[test]
fn parse_follow_nodes() {
let src = "root\n
weight 0 < 1\n
if weight next:now store\n
;\n
\n
store\n
if !some_item \"welcome, \nlook around\"\n
;";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let ev = Evaluator::new(&mut env);
let (vars,_) = ev.last().unwrap();
assert_eq!(vars[0], "welcome, \nlook around".into());
}
#[test]
fn parse_select_nodes() {
let src = "root\n
next:select {\"Head to Store?\" store,\n
\"Leave the town?\" exit-town}\n
\n
if !some_item [\"Some choices\"
next:select {\"Head to Store?\" store2,\n
\"Leave the town?\" exit-town2}]\n
\n
next:select {\"Head to town?\" store3 bakery tanner,\n
5 hike,
\"Leave the town?\" exit-town3}\n
\n
emit \"A dustball blows by\"\n
;";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (_vars,select1) = ev.next().unwrap();
let (_vars,select2) = ev.next().unwrap();
assert_ne!(select1,select2);
let mut map: Map = HashMap::new();
map.insert("Head to Store?".to_owned(), vec![Var::Sym("store2".to_owned())]);
map.insert("Leave the town?".to_owned(), vec![Var::Sym("exit-town2".to_owned())]);
assert_eq!(select2, Some(Next::Select(map)));
let (_,select) = ev.next().unwrap();
match select.expect("Unable to parse map") {
Next::Select(map) => {
println!("Map: {:?}",map);
assert!(map.contains_key("5"));
assert_eq!(map.get("5"), Some(&vec![Var::Sym("hike".to_owned())]));
},
_ => { panic!("Invalid Next type found") }
}
}
#[test]
fn parse_next_back_restart() {
let src = "root\n
next:call step2
next:restart\n
;\n
step2
next:back\n
emit \"something\"\n
;\n";
let p = Parser::parse_blocks(src).expect("ERROR: Unable to parse source");
let mut env = p.into_env();
let mut ev = Evaluator::new(&mut env);
let (_,next) = ev.next().unwrap();
assert_eq!(next, Some(Next::Call("step2".to_owned())));
let (_,next) = ev.next().unwrap();
assert_eq!(next, Some(Next::Back));
let (_,next) = ev.next().unwrap();
assert_eq!(next, Some(Next::Restart(None)));
}
#[test]
fn parse_or_logic() {
let src = "root\n
has_weight 101 < 100\n
if !has_weight \"can add stuff\"\n
or \"too heavy!\"\n
;\n";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (vars,_) = ev.next().unwrap();
assert_eq!(vars[0], "can add stuff".into());
}
#[test]
fn validate_inv_logic() {
let src = "root\n
if !global.name \"missing name\"\n
or \"name is `global.name\"\n
\n
if global.is_false \"is_false\"\n
when {!global.name @global.name \"new-name\"}\n
emit global.name\n
;\n
def global\n
is_false false\n
;\n";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (vars,_) = ev.next().unwrap();
assert_eq!(vars[0], "missing name".into());
let (vars,_) = ev.next().unwrap();
assert_eq!(vars[0], "new-name".into());
}
#[test]
fn obj_dupe_as_nested() {
let src = "def daggers\n
damage 1.5\n
;\n
root\n
@player.dagger new daggers\n
emit player.dagger.damage\n
;\n";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (vars,_) = ev.next().unwrap();
assert_eq!(vars[0], 1.5 .into());
}
#[test]
fn obj_dupe_mut() {
let src = "def daggers\n
damage 1.5\n
;\n
root\n
@player.dagger new daggers\n
@player.dagger.age 5\n
emit player.dagger.age\n
;\n";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (vars,_) = ev.next().unwrap();
assert_eq!(vars[0], 5. .into());
}
#[test]
fn obj_from_scratch() {
let src = "root\n
@player.dagger.age 5\n
emit player.dagger.age\n
;\n";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (vars,_) = ev.next().unwrap();
assert_eq!(vars[0], 5. .into());
}
#[test]
fn inline_logic_inv() {
let src = "root\n
weight 4 < 5\n
if !weight 4.\n
\n
weight2 5 < 4\n
if !weight2 5.\n
;\n";
let mut env = Parser::parse_blocks(src).expect("ERROR: Unable to parse source").into_env();
let mut ev = Evaluator::new(&mut env);
let (vars,_) = ev.next().unwrap();
assert_eq!(vars[0], 5. .into());
}