use super::{StudioTypeKind, build};
const DOCUMENTED: &str = "\
//! Grading.
workflow grade
input essay: String
outcome graded: type String, route success
/// What a marker decided.
type Verdict {
/// The mark itself.
grade: String,
}
/// How sure the marker was.
type Confidence =
/// No doubt at all.
| Certain
| Unsure
/// The queue that marks essays.
worker marker
/// Read one essay and settle on a grade.
action mark(
/// The text to read.
essay: String,
) -> Verdict
step mark
mark(essay: essay) -> verdict
outcome graded: else, route graded(verdict.grade)
";
const UNDOCUMENTED: &str = "\
//! Grading.
workflow grade
input essay: String
outcome graded: type String, route success
type Verdict { grade: String }
type Confidence = Certain | Unsure
worker marker
action mark(essay: String) -> Verdict
step mark
mark(essay: essay) -> verdict
outcome graded: else, route graded(verdict.grade)
";
#[test]
fn the_projection_carries_the_prose_and_carries_its_absence()
-> Result<(), Box<dyn std::error::Error>> {
let documented = build(&aion_awl::parse(DOCUMENTED)?);
let verdict = documented
.types
.iter()
.find(|ty| ty.name == "Verdict")
.ok_or("the projection names the declared record")?;
assert_eq!(verdict.kind, StudioTypeKind::Record);
assert_eq!(
verdict.documentation.as_deref(),
Some("What a marker decided.")
);
assert_eq!(
verdict.fields[0].documentation.as_deref(),
Some("The mark itself.")
);
let confidence = documented
.types
.iter()
.find(|ty| ty.name == "Confidence")
.ok_or("the projection names the declared enum")?;
assert_eq!(
confidence.variants[0].documentation.as_deref(),
Some("No doubt at all.")
);
assert!(
confidence.variants[1].documentation.is_none(),
"an undocumented variant projects its absence"
);
let worker = documented
.workers
.first()
.ok_or("the projection names the declared worker")?;
assert_eq!(
worker.documentation.as_deref(),
Some("The queue that marks essays.")
);
let action = worker
.actions
.first()
.ok_or("the projection names the declared action")?;
assert_eq!(
action.documentation.as_deref(),
Some("Read one essay and settle on a grade.")
);
assert_eq!(
action.params[0].documentation.as_deref(),
Some("The text to read.")
);
let plain = build(&aion_awl::parse(UNDOCUMENTED)?);
for ty in &plain.types {
assert!(ty.documentation.is_none(), "`{}` carries no prose", ty.name);
for field in &ty.fields {
assert!(field.documentation.is_none());
}
for variant in &ty.variants {
assert!(variant.documentation.is_none());
}
}
for worker in &plain.workers {
assert!(worker.documentation.is_none());
for action in &worker.actions {
assert!(action.documentation.is_none());
for param in &action.params {
assert!(param.documentation.is_none());
}
}
}
Ok(())
}
#[test]
fn the_projection_serialises_an_absent_sentence_as_null() -> Result<(), Box<dyn std::error::Error>>
{
let plain = build(&aion_awl::parse(UNDOCUMENTED)?);
let encoded = serde_json::to_value(&plain)?;
let documentation = &encoded["types"][0]["documentation"];
assert!(
documentation.is_null(),
"an undocumented type must encode as null, got {documentation}"
);
Ok(())
}