use formally::{
io::{parse::*, print::Print},
support::*,
};
use formally::smt::smtlib;
use rstest::*;
use std::{fmt::Debug, io::Cursor};
#[rstest]
#[case("255", smtlib::ast::Numeral::parser())]
#[case("3.14", smtlib::ast::Decimal::parser())]
#[case("#abba", smtlib::ast::Hexadecimal::parser())]
#[case("#b101", smtlib::ast::Binary::parser())]
#[case("\"ciao \"\"mondo\"\"!\"", smtlib::ast::StringLiteral::parser())]
#[case("Array", smtlib::ast::Index::parser())]
#[case("3", smtlib::ast::Index::parser())]
#[case("Array", smtlib::ast::Identifier::parser())]
#[case("|Array LoL|", smtlib::ast::Identifier::parser())]
#[case("(_ Array 3 Int)", smtlib::ast::Identifier::parser())]
#[case("(_ Array 3 Int)", smtlib::ast::Sort::parser())]
#[case(
"(as pippo (_ Array 3 Int))",
smtlib::ast::QualifiedIdentifier::parser()
)]
#[case("((as pippo (_ Array 3 Int)) 42)", smtlib::ast::Term::parser())]
#[case("(let ((x 20) (y 22)) (+ x y))", smtlib::ast::Term::parser())]
#[case("(lambda ((x Int) (y Int)) (+ x y))", smtlib::ast::Term::parser())]
#[case("(exists ((x Int) (y Int)) (+ x y))", smtlib::ast::Term::parser())]
#[case("(forall ((x Int) (y Int)) (+ x y))", smtlib::ast::Term::parser())]
#[case("(assert (= 42 (+ 20 22)))", smtlib::ast::Command::parser())]
#[case(
"(check-sat-assuming ((< x 42) (> x 42)))",
smtlib::ast::Command::parser()
)]
#[case(
"(declare-fun index ((_ Array 3 Int) Int) Int)",
smtlib::ast::Command::parser()
)]
#[case("(define-const pi Real 3.14)", smtlib::ast::Command::parser())]
pub fn successes<T: Debug + Print>(
#[case] input: &str,
#[case] parser: Parser<'_, T>,
) -> std::io::Result<()> {
let mut output = Vec::new();
let mut cursor = Cursor::new(&mut output);
eprintln!("parsing: {input}...");
let emitter = StdErrEmitter::new();
let result = parser.parse(&emitter, input);
match result {
Ok(out) => {
eprintln!(" - parsed!");
eprintln!("{:?}", out);
out.render(&mut cursor, 80)?;
assert_eq!(String::from_utf8(output).unwrap(), input);
}
Err(err) => {
eprintln!(" - parsing error: {err:?}");
unreachable!()
}
}
Ok(())
}