#[cfg(test)]
mod test {
extern crate alloc;
use alloc::collections::{BTreeMap, BTreeSet};
use clojure_reader::edn::{self, Edn};
#[test]
fn parse_empty() {
assert_eq!(edn::read_string("").unwrap(), Edn::Nil);
assert_eq!(edn::read_string("#_42").unwrap(), Edn::Nil);
assert_eq!(edn::read_string("[]").unwrap(), Edn::Vector(Vec::new()));
assert_eq!(edn::read_string("()").unwrap(), Edn::List(Vec::new()));
assert_eq!(edn::read_string("{}").unwrap(), Edn::Map(BTreeMap::new()));
}
#[test]
fn strings() {
assert_eq!(edn::read_string("\"猫 are 猫\"").unwrap(), Edn::Str("猫 are 猫"));
assert_eq!(edn::read_string(r#""foo\rbar""#).unwrap(), Edn::Str("foo\\rbar"));
}
#[test]
fn maps() {
let e = "{
:cat \"猫\" ; this is utf-8
:num -0x9042
:r 42/4242
#_#_:num 9042
{:foo \"bar\"} \"foobar\"
; dae paren
:lisp (())
}";
assert_eq!(
edn::read_string(e).unwrap(),
Edn::Map(BTreeMap::from([
(Edn::Key("cat"), Edn::Str("猫")),
(Edn::Key("num"), Edn::Int(-36930)),
(Edn::Map(BTreeMap::from([(Edn::Key("foo"), Edn::Str("bar"))])), Edn::Str("foobar")),
(Edn::Key("r"), Edn::Rational((42, 4242))),
(Edn::Key("lisp"), Edn::List(vec![Edn::List(vec![])])),
]))
);
}
#[test]
fn whitespace() {
let expected_result = Edn::Map(BTreeMap::from([(
Edn::Key("somevec"),
Edn::Vector(vec![Edn::Map(BTreeMap::from([(Edn::Key("value"), Edn::Int(42))]))]),
)]));
let e = "{:somevec
[{:value 42},]
}";
assert_eq!(edn::read_string(e).unwrap(), expected_result);
let e = "{:somevec
[{:value 42}
]
}";
assert_eq!(edn::read_string(e).unwrap(), expected_result);
let e = "{:somevec
[ {:value 42} ; lol
]
}";
assert_eq!(edn::read_string(e).unwrap(), expected_result);
}
#[test]
fn sets() {
let e = "#{:cat 1 true #{:cat true} 2 [42]}";
assert_eq!(
edn::read_string(e).unwrap(),
Edn::Set(BTreeSet::from([
Edn::Key("cat"),
Edn::Int(1),
Edn::Bool(true),
Edn::Set(BTreeSet::from([Edn::Key("cat"), Edn::Bool(true)])),
Edn::Int(2),
(Edn::Vector(vec![Edn::Int(42)])),
]))
);
}
#[test]
fn numbers() {
assert_eq!(edn::read_string("43/5143").unwrap(), Edn::Rational((43, 5143)));
assert_eq!(
edn::read_string("-1190128294822145183/3023870813131455535").unwrap(),
Edn::Rational((-1190128294822145183, 3023870813131455535))
);
assert_eq!(
edn::read_string("-2477641376863858799/-8976013293400652448").unwrap(),
Edn::Rational((-2477641376863858799, -8976013293400652448))
);
}
#[test]
fn parse_0x_ints() {
assert_eq!(edn::read_string("0x2a").unwrap(), Edn::Int(42));
assert_eq!(edn::read_string("-0X2A").unwrap(), Edn::Int(-42));
assert_eq!(edn::read_string("+42").unwrap(), Edn::Int(42));
assert_eq!(edn::read_string("+0x2a").unwrap(), Edn::Int(42));
}
#[test]
fn parse_radix_ints() {
assert_eq!(edn::read_string("16r2a").unwrap(), Edn::Int(42));
assert_eq!(edn::read_string("8r63").unwrap(), Edn::Int(51));
assert_eq!(edn::read_string("36rabcxyz").unwrap(), Edn::Int(623_741_435));
assert_eq!(edn::read_string("-16r2a").unwrap(), Edn::Int(-42));
assert_eq!(edn::read_string("-32rFOObar").unwrap(), Edn::Int(-529_280_347));
}
#[test]
fn lisp_quoted() {
assert_eq!(
edn::read_string("('(symbol))").unwrap(),
Edn::List(vec![Edn::Symbol("'"), Edn::List(vec![Edn::Symbol("symbol"),])])
);
assert_eq!(
edn::read_string("(apply + '(1 2 3))").unwrap(),
Edn::List(vec![
Edn::Symbol("apply"),
Edn::Symbol("+"),
Edn::Symbol("'"),
Edn::List(vec![Edn::Int(1), Edn::Int(2), Edn::Int(3),])
])
);
assert_eq!(
edn::read_string("('(''symbol'foo''bar''))").unwrap(),
Edn::List(vec![Edn::Symbol("'"), Edn::List(vec![Edn::Symbol("''symbol'foo''bar''"),])])
);
}
#[test]
fn numeric_like_symbols() {
assert_eq!(edn::read_string("-foobar").unwrap(), Edn::Symbol("-foobar"));
assert_eq!(
edn::read_string("(+foobar +foo+bar+ +'- '-+)").unwrap(),
Edn::List(vec![
Edn::Symbol("+foobar"),
Edn::Symbol("+foo+bar+"),
Edn::Symbol("+'-"),
Edn::Symbol("'-+"),
])
);
assert!(edn::read_string("(-foo( ba").is_err());
}
#[test]
fn special_chars() {
assert_eq!(edn::read_string("\\c[lolthisisvalidedn").unwrap(), Edn::Char('c'),);
let edn = "[\\space \\@ \\` \\tab \\return \\newline \\# \\% \\' \\g \\( \\* \\j \\+ \\, \\l \\- \\. \\/ \\0 \\2 \\r \\: \\; \\< \\\\ \\] \\} \\~ \\? \\_]";
assert_eq!(
edn::read_string(edn).unwrap(),
Edn::Vector(vec![
Edn::Char(' '),
Edn::Char('@'),
Edn::Char('`'),
Edn::Char('\t'),
Edn::Char('\r'),
Edn::Char('\n'),
Edn::Char('#'),
Edn::Char('%'),
Edn::Char('\''),
Edn::Char('g'),
Edn::Char('('),
Edn::Char('*'),
Edn::Char('j'),
Edn::Char('+'),
Edn::Char(','),
Edn::Char('l'),
Edn::Char('-'),
Edn::Char('.'),
Edn::Char('/'),
Edn::Char('0'),
Edn::Char('2'),
Edn::Char('r'),
Edn::Char(':'),
Edn::Char(';'),
Edn::Char('<'),
Edn::Char('\\'),
Edn::Char(']'),
Edn::Char('}'),
Edn::Char('~'),
Edn::Char('?'),
Edn::Char('_'),
])
);
}
#[test]
fn read_forms() {
let s = "(def foo 42)(sum '(1 2 3)) #_(foo the bar (cat)) 42 nil 2";
let (e, s) = edn::read(s).unwrap();
assert_eq!(e, Edn::List(vec![Edn::Symbol("def"), Edn::Symbol("foo"), Edn::Int(42)]));
let (e, s) = edn::read(s).unwrap();
assert_eq!(
e,
Edn::List(vec![
Edn::Symbol("sum"),
Edn::Symbol("'"),
Edn::List(vec![Edn::Int(1), Edn::Int(2), Edn::Int(3)])
])
);
let (e, s) = edn::read(s).unwrap();
assert_eq!(e, Edn::Int(42));
let (e, s) = edn::read(s).unwrap();
assert_eq!(e, Edn::Nil);
let (e, s) = edn::read(s).unwrap();
assert_eq!(e, Edn::Int(2));
assert!(edn::read(s).is_err());
}
#[test]
fn tagged() {
assert_eq!(
edn::read_string("#inst \"1985-04-12T23:20:50.52Z\"").unwrap(),
Edn::Tagged("inst", Box::new(Edn::Str("1985-04-12T23:20:50.52Z")))
);
assert_eq!(edn::read_string(r#"#Unit nil"#).unwrap(), Edn::Tagged("Unit", Box::new(Edn::Nil)));
}
}