use std::path::{Path, PathBuf};
use std::process::Command;
fn fixture() -> PathBuf {
let test = std::thread::current()
.name()
.unwrap_or("t")
.replace(':', "-");
let dir = std::env::temp_dir().join(format!("quarb-stream-json-{}-{test}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
let titles = ["Iliad", "Odyssey", "Aeneid", "Emma", "Persuasion", "Hamlet"];
let authors = ["Homer", "Virgil", "Austen", "Shakespeare", "Herodotus"];
let mut books = Vec::new();
for i in 0..6000u32 {
let mut b = format!(
"{{\"id\": {i}, \"title\": \"{} {i}\", \"author\": \"{}\", \"price\": {}.{:02}, \"tags\": [\"a\", \"b\"]",
titles[(i as usize * 7) % titles.len()],
authors[(i as usize * 3) % authors.len()],
5 + (i * 37) % 55,
(i * 13) % 100
);
if i % 11 != 0 {
b.push_str(&format!(", \"year\": {}", -800 + ((i as i64 * 101) % 2700)));
}
if i % 7 == 0 {
b.push_str(&format!(", \"ref\": \"#/books/{}\"", i.saturating_sub(1)));
}
b.push('}');
books.push(b);
}
let array = books.join(",\n ");
std::fs::write(
dir.join("keyed.json"),
format!("{{\"meta\": {{\"n\": 6000, \"source\": \"test\"}},\n \"books\": [\n {array}\n ],\n \"note\": \"end\"}}\n"),
)
.unwrap();
std::fs::write(dir.join("root.json"), format!("[{array}]")).unwrap();
dir
}
fn qua(dir: &Path, args: &[&str]) -> (String, String, bool) {
let out = Command::new(env!("CARGO_BIN_EXE_qua"))
.current_dir(dir)
.env("QUARB_LOCALE", "C")
.env("HOME", dir)
.args(args)
.output()
.unwrap();
(
String::from_utf8_lossy(&out.stdout).trim().to_string(),
String::from_utf8_lossy(&out.stderr).trim().to_string(),
out.status.success(),
)
}
#[test]
fn the_streamed_document_answers_as_the_whole_read() {
let d = fixture();
for (q, f) in [
("/books/* @| count", "keyed.json"),
("/books/*[..3] | ::title", "keyed.json"),
("/books/*[::year > 1800] @| count", "keyed.json"),
("/books/*[::year > 1800] | ::title | first", "keyed.json"),
("//title @| count", "keyed.json"),
("/meta | %", "keyed.json"),
("/note | ::", "keyed.json"),
("/books @| count", "keyed.json"),
("/books:::length", "keyed.json"),
("/books:::type", "keyed.json"),
("/books/*[2]/tags/* | ::", "keyed.json"),
("/books/*[8]/ref--> | ::title", "keyed.json"),
("/books/* | ::price | sum", "keyed.json"),
("/* @| count", "root.json"),
("/*[..2] | ::title", "root.json"),
("/*[::author = \"Homer\"] @| count", "root.json"),
("//tags/* @| count", "root.json"),
("/*[3] | %", "root.json"),
] {
let (a, ea, ga) = qua(&d, &[q, f]);
let (b, eb, gb) = qua(&d, &["--no-stream", q, f]);
assert_eq!(ga, gb, "{q} on {f}: {ea} / {eb}");
assert_eq!(a, b, "{q} on {f}");
}
let (out, err, good) = qua(&d, &["/books/* @| count", "keyed.json"]);
assert!(good, "{err}");
assert_eq!(out, "6000");
let (out, _, _) = qua(&d, &["/*[::author = \"Homer\"] @| count", "root.json"]);
assert_eq!(out, "1200");
}