use super::description::QueryDescription;
use super::identifier::QueryIdentifier;
use super::script::QueryScript;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Query {
pub name: QueryIdentifier,
pub script: QueryScript,
pub description: Option<QueryDescription>,
}
impl Query {
pub fn new(
name: QueryIdentifier,
script: QueryScript,
description: Option<QueryDescription>,
) -> Self {
Self {
name,
script,
description,
}
}
}
#[cfg(test)]
pub mod strategy {
use super::super::description::strategy::query_description;
use super::super::identifier::strategy::query_identifier;
use super::super::script::strategy::query_script;
use super::Query;
use proptest::prelude::*;
prop_compose! {
pub fn query()(
name in query_identifier(),
script in query_script(),
description in proptest::option::of(query_description()),
) -> Query {
Query::new(name, script, description)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn round_trip_fields(q in strategy::query()) {
let again = Query::new(q.name.clone(), q.script.clone(), q.description.clone());
prop_assert_eq!(again, q);
}
}
fn name(s: &str) -> QueryIdentifier {
QueryIdentifier::new(s).unwrap()
}
#[test]
fn carries_an_optional_description() {
let q = Query::new(
name("counts"),
QueryScript::new("?[n] := n = 1\n"),
Some(QueryDescription::new("number of issues")),
);
assert_eq!(
q.description.as_ref().map(|d| d.as_str()),
Some("number of issues")
);
}
#[test]
fn description_is_optional() {
let q = Query::new(name("counts"), QueryScript::new("?[n] := n = 1\n"), None);
assert!(q.description.is_none());
}
}