use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, Mutex};
use ticklog::{info, Level, LogSink};
struct CaptureSink {
lines: Arc<Mutex<Vec<String>>>,
}
impl LogSink for CaptureSink {
fn accept(&mut self, line: &[u8], _level: Level) -> std::io::Result<()> {
self.lines
.lock()
.unwrap()
.push(String::from_utf8_lossy(line).into_owned());
Ok(())
}
}
#[test]
fn each_argument_is_evaluated_once_and_arity_is_unbounded() {
let lines = Arc::new(Mutex::new(Vec::new()));
let sink = CaptureSink {
lines: Arc::clone(&lines),
};
let guard = ticklog::builder()
.sink(sink)
.max_level(Level::Trace)
.build()
.expect("first build in a fresh process must succeed");
let ctr = AtomicU64::new(0);
info!("seq={}", ctr.fetch_add(1, Ordering::Relaxed));
info!(
"{} {} {} {} {} {} {} {} {} {} {} {}",
0u64, 1u64, 2u64, 3u64, 4u64, 5u64, 6u64, 7u64, 8u64, 9u64, 10u64, 11u64
);
drop(guard);
let captured = lines.lock().unwrap();
assert_eq!(
ctr.load(Ordering::Relaxed),
1,
"argument must be evaluated once, not multiple times"
);
assert!(
captured[0].ends_with("seq=0"),
"encoded value must come from the single evaluation; got {:?}",
captured[0]
);
assert!(
captured[1].ends_with("0 1 2 3 4 5 6 7 8 9 10 11"),
"all arguments must be encoded; got {:?}",
captured[1]
);
}