extern crate cirru_parser;
use cirru_parser::escape_cirru_leaf;
#[cfg(feature = "serde-json")]
mod json_write_test {
use super::*;
use cirru_parser::{Cirru, CirruWriterOptions, format, from_json_str};
use std::fs;
use std::io;
#[test]
fn write_demo() -> Result<(), String> {
let writer_options = CirruWriterOptions { use_inline: false };
match from_json_str(r#"[["a"], ["b"]]"#) {
Ok(tree) => {
if let Cirru::List(xs) = tree {
assert_eq!("\na\n\nb\n", format(&xs, writer_options)?)
} else {
panic!("unexpected leaf here")
}
}
Err(e) => {
println!("file err: {e}");
panic!("failed to load edn data from JSON");
}
};
if let Cirru::List(xs) = from_json_str(r#"[["中文"], ["中文"]]"#).unwrap() {
assert_eq!("\n\"中文\"\n\n\"中文\"\n", format(&xs, writer_options)?)
} else {
panic!("unexpected leaf here")
}
Ok(())
}
#[test]
fn write_files() -> Result<(), io::Error> {
let files = vec![
"append-indent",
"comma-indent",
"cond-short",
"cond",
"demo",
"double-nesting",
"fold-vectors",
"folding",
"html",
"indent",
"inline-let",
"inline-simple",
"line",
"nested-2",
"parentheses",
"quote",
"spaces",
"unfolding",
"list-match",
"tag-match",
];
for file in files {
println!("testing file: {file}");
let json_str = fs::read_to_string(format!("./tests/writer_data/{file}.json"))?;
let cirru_str = fs::read_to_string(format!("./tests/writer_cirru/{file}.cirru"))?;
let writer_options = CirruWriterOptions { use_inline: false };
match from_json_str(&json_str) {
Ok(tree) => {
if let Cirru::List(xs) = tree {
assert_eq!(cirru_str, format(&xs, writer_options).unwrap());
} else {
panic!("unexpected leaf here")
}
}
Err(e) => {
println!("{e:?}");
panic!("failed to load edn data from json");
}
}
}
Ok(())
}
#[test]
fn write_with_inline() -> Result<(), io::Error> {
let files = vec!["html-inline", "inline-mode"];
for file in files {
println!("testing file: {file}");
let json_str = fs::read_to_string(format!("./tests/writer_data/{file}.json"))?;
let cirru_str = fs::read_to_string(format!("./tests/writer_cirru/{file}.cirru"))?;
let writer_options = CirruWriterOptions { use_inline: true };
match from_json_str(&json_str) {
Ok(tree) => {
if let Cirru::List(xs) = tree {
assert_eq!(cirru_str, format(&xs, writer_options).unwrap());
} else {
panic!("unexpected literal here")
}
}
Err(e) => {
println!("file err: {e:?}");
panic!("failed to load edn form data");
}
}
}
Ok(())
}
}
#[test]
fn leaves_escapeing() {
assert_eq!("\"a\"", escape_cirru_leaf("a"));
assert_eq!("\"a b\"", escape_cirru_leaf("a b"));
assert_eq!("\"a!+-b\"", escape_cirru_leaf("a!+-b"));
assert_eq!("\"a\\nb\"", escape_cirru_leaf("a\nb"));
assert_eq!("\"中文\"", escape_cirru_leaf("中文"));
assert_eq!("\"中文\\n\"", escape_cirru_leaf("中文\n"));
}
#[test]
fn leaf_single_quote_without_quotes() -> Result<(), String> {
use cirru_parser::{Cirru, CirruWriterOptions, format};
let xs = vec![Cirru::List(vec![Cirru::leaf("foo'bar")])];
let rendered = format(&xs, CirruWriterOptions::from(false))?;
assert_eq!("\nfoo'bar\n", rendered);
Ok(())
}
#[test]
fn leaf_single_quote_with_spaces_requires_quotes() -> Result<(), String> {
use cirru_parser::{Cirru, CirruWriterOptions, format};
let xs = vec![Cirru::List(vec![Cirru::leaf("foo bar'baz")])];
let rendered = format(&xs, CirruWriterOptions::from(false))?;
assert_eq!("\n\"foo bar'baz\"\n", rendered);
Ok(())
}
#[test]
fn test_writer_options_from_bool() -> Result<(), String> {
use cirru_parser::{Cirru, CirruWriterOptions, format};
let xs = vec![Cirru::List(vec![
Cirru::leaf("a"),
Cirru::List(vec![Cirru::leaf("c"), Cirru::leaf("b")]),
Cirru::List(vec![Cirru::leaf("d"), Cirru::leaf("e")]),
Cirru::List(vec![Cirru::leaf("g"), Cirru::leaf("h")]),
])];
let inline_result = format(&xs, true.into())?;
let non_inline_result = format(&xs, false.into())?;
assert_ne!(inline_result, non_inline_result);
assert!(non_inline_result.contains("\n"));
let inline_from_result = format(&xs, CirruWriterOptions::from(true))?;
let non_inline_from_result = format(&xs, CirruWriterOptions::from(false))?;
assert_eq!(inline_result, inline_from_result);
assert_eq!(non_inline_result, non_inline_from_result);
Ok(())
}
#[cfg(feature = "serde-json")]
#[test]
fn test_dollar_sign_spacing() -> Result<(), String> {
use cirru_parser::{Cirru, CirruWriterOptions, format, from_json_str};
let json_str = r#"[
[
"tag-match",
"self",
[
[
":plugin",
"node",
"cursor",
"state"
],
[
"d!",
"cursor",
[
"assoc",
"state",
":show?",
"false"
]
]
]
]
]"#;
let writer_options = CirruWriterOptions { use_inline: false };
match from_json_str(json_str) {
Ok(tree) => {
if let Cirru::List(xs) = tree {
let result = format(&xs, writer_options)?;
println!("Formatted result:\n{}", result);
assert!(!result.contains("$ \n"), "Found unexpected '$ \\n' pattern in output");
Ok(())
} else {
panic!("unexpected leaf here")
}
}
Err(e) => {
println!("parse error: {e}");
Err(format!("failed to parse JSON: {e}"))
}
}
}