use crate::cst::{SyntaxKind, CST};
use crate::{Parser, Span};
#[test]
fn cst_1() {
let cst: CST =
Parser::new(b"rule test { condition: true }").try_into().unwrap();
let source_file = cst.root();
assert_eq!(source_file.kind(), SyntaxKind::SOURCE_FILE);
assert_eq!(source_file.parent(), None);
assert_eq!(source_file.prev_sibling(), None);
assert_eq!(source_file.next_sibling(), None);
let rule_decl = source_file.first_child();
assert_eq!(source_file.last_child(), rule_decl);
let mut children = source_file.children();
assert_eq!(children.next(), rule_decl);
assert_eq!(children.next(), None);
let rule_decl = rule_decl.unwrap();
assert_eq!(rule_decl.parent(), Some(source_file.clone()));
let condition_blk = rule_decl.first_child();
assert_eq!(rule_decl.last_child(), condition_blk);
let condition_blk = condition_blk.unwrap();
assert_eq!(condition_blk.span(), Span(12..27));
let mut ancestors = condition_blk.ancestors();
assert_eq!(ancestors.next(), Some(rule_decl.clone()));
assert_eq!(ancestors.next(), Some(source_file.clone()));
assert_eq!(ancestors.next(), None);
let mut c = condition_blk.children_with_tokens();
assert_eq!(c.next().map(|c| c.kind()), Some(SyntaxKind::CONDITION_KW));
assert_eq!(c.next().map(|c| c.kind()), Some(SyntaxKind::COLON));
assert_eq!(c.next().map(|c| c.kind()), Some(SyntaxKind::WHITESPACE));
assert_eq!(c.next().map(|c| c.kind()), Some(SyntaxKind::BOOLEAN_EXPR));
assert_eq!(c.next().map(|c| c.kind()), None);
let mut t = condition_blk.first_token().unwrap();
assert_eq!(t.kind(), SyntaxKind::CONDITION_KW);
t = t.next_token().unwrap();
assert_eq!(t.kind(), SyntaxKind::COLON);
t = t.next_token().unwrap();
assert_eq!(t.kind(), SyntaxKind::WHITESPACE);
t = t.next_token().unwrap();
assert_eq!(t.kind(), SyntaxKind::TRUE_KW);
t = t.next_token().unwrap();
assert_eq!(t.kind(), SyntaxKind::WHITESPACE);
t = t.next_token().unwrap();
assert_eq!(t.kind(), SyntaxKind::R_BRACE);
assert_eq!(t.next_token(), None);
let mut ancestors = t.ancestors();
assert_eq!(ancestors.next(), Some(rule_decl.clone()));
assert_eq!(ancestors.next(), Some(source_file.clone()));
assert_eq!(ancestors.next(), None);
}
#[test]
fn cst_2() {
let cst: CST =
Parser::new(b"rule test { condition: true }").try_into().unwrap();
let mut c = cst.root().first_child().unwrap().children_with_tokens();
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::RULE_KW));
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::WHITESPACE));
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::IDENT));
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::WHITESPACE));
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::L_BRACE));
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::WHITESPACE));
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::CONDITION_BLK));
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::WHITESPACE));
assert_eq!(c.next().map(|n| n.kind()), Some(SyntaxKind::R_BRACE));
assert_eq!(c.next().map(|n| n.kind()), None);
let c = cst.root().first_child().unwrap().first_child_or_token().unwrap();
assert_eq!(c.parent().map(|n| n.kind()), Some(SyntaxKind::RULE_DECL));
let mut a = c.ancestors();
assert_eq!(a.next().map(|n| n.kind()), Some(SyntaxKind::RULE_DECL));
assert_eq!(a.next().map(|n| n.kind()), Some(SyntaxKind::SOURCE_FILE));
assert_eq!(a.next().map(|n| n.kind()), None);
assert_eq!(
c.next_sibling_or_token().map(|n| n.kind()),
Some(SyntaxKind::WHITESPACE)
);
let c = cst.root().first_child().unwrap().last_child_or_token().unwrap();
assert_eq!(
c.prev_sibling_or_token().map(|n| n.kind()),
Some(SyntaxKind::WHITESPACE)
);
}
#[test]
fn cst_3() {
let cst: CST =
Parser::new(b"rule test { condition: true }").try_into().unwrap();
let condition_blk =
cst.root().first_child().unwrap().first_child().unwrap();
let text = condition_blk.text();
assert!(!text.is_empty());
assert_eq!(text.len(), 15);
let chunks = text
.try_fold_chunks::<_, _, anyhow::Error>(Vec::new(), |mut acc, s| {
acc.push(s.to_string());
Ok(acc)
})
.unwrap();
assert_eq!(chunks, ["condition", ":", " ", "true"]);
let mut chunks = Vec::new();
text.for_each_chunks(|s| {
chunks.push(s.to_string());
});
assert_eq!(chunks, ["condition", ":", " ", "true"]);
let result = text.try_for_each_chunks(|s| {
if s == ":" {
anyhow::bail!("colon found")
} else {
Ok(())
}
});
assert!(result.is_err());
}
#[test]
fn cst_4() {
let cst: CST =
Parser::new(b"rule test { condition: true }").try_into().unwrap();
let source_file = cst.root().into_mut();
source_file.first_token().unwrap().detach();
assert_eq!(
source_file.first_token().map(|x| x.kind()),
Some(SyntaxKind::WHITESPACE)
);
source_file.last_token().unwrap().detach();
assert_eq!(
source_file.last_token().map(|x| x.kind()),
Some(SyntaxKind::WHITESPACE)
);
source_file.first_child_or_token().unwrap().detach();
assert_eq!(source_file.last_token().map(|x| x.kind()), None);
}