Standalone illustrative diagram playback for diagrams.mbt
///|
test "render an offline sequence illustration" {
let sequence = @sequence.Sequence::new(
[@sequence.Participant::new("Client"), @sequence.Participant::new("API")],
[
Message(@sequence.Message::new("Client", "API", "request")),
Message(@sequence.Message::new("API", "API", "work")),
Message(@sequence.Message::new("API", "Client", "reply")),
],
)
let result = @animated.AnimatedRenderer::new().render(Sequence(sequence))
assert_eq(result.media_type, "text/html")
assert_true(result.output.unwrap().contains("data-control=\"seek\""))
assert_true(result.output.unwrap().contains("Download SVG"))
}///|
test "render a finite concurrent BPMN scenario" {
let view = @model.Bpmn::new(
"P",
[
@model.Node::new("A", Task, label="Review"),
@model.Node::new("B", Task, label="Record"),
],
[@model.Flow::new("AB", "A", "B"), @model.Flow::new("BA", "B", "A")],
)
let catalog = @animation.Catalog::bpmn(view).catalog.unwrap()
let a = catalog.flow("AB").unwrap().key
let b = catalog.flow("BA").unwrap().key
let playback = @animation.PlaybackPlan::scenario(
catalog,
@animation.Motion::serial([
@animation.Motion::parallel([Step(a, 1000L), Step(b, 500L)]),
Step(a, 1000L),
]),
).plan.unwrap()
let result = @animated.AnimatedRenderer::new(playback~).render(Bpmn(view))
assert_true(result.output != None)
assert_true(result.output.unwrap().contains("Explicit scenario"))
}///|
test "play a curved sequence with the same canonical SVG" {
let model = @sequence.Sequence::new([@sequence.Participant::new("Worker")], [
Message(@sequence.Message::new("Worker", "Worker", "retry")),
])
let svg = @svg.SvgRenderer::new(
connectors=@svg.ConnectorOptions::new(style=Curved),
)
let diagram = @render.Diagram::Sequence(model)
let scene = svg.scene(diagram).scene.unwrap()
assert_eq(scene.canonical_svg, svg.render(diagram).output.unwrap())
assert_true(scene.paths[0].path.contains("C"))
let output = @animated.AnimatedRenderer::new(svg~).render(diagram)
assert_true(output.output is Some(_))
}///|
test "render a finite reverse swimlane scenario" {
let view = @swimlane.Swimlane::new(
"Review",
[@swimlane.Node::new("A"), @swimlane.Node::new("B")],
[@swimlane.Connection::new("AB", "A", "B", source_marker=Arrow)],
)
let catalog = @animation.Catalog::swimlane(view).catalog.unwrap()
guard catalog.graph.route("B", "A") is Found(route) else {
fail("missing return")
}
let playback = @animation.PlaybackPlan::route(catalog, route).plan.unwrap()
let output = @animated.AnimatedRenderer::new(playback~).render(Swimlane(view))
assert_true(output.output is Some(_))
assert_eq(output.media_type, "text/html")
}///|
test "play a regex railroad with term visits" {
let model = @regex.Regex::new("ab", "s", [
@regex.Node::new("s", Sequence(["a", "b"])),
@regex.Node::new("a", Literal("a")),
@regex.Node::new("b", Literal("b")),
])
let output = @render.Renderer::render(
@animated.AnimatedRenderer::new(),
Regex(model),
)
let html = output.output.unwrap()
assert_true(html.contains("\"visit\":true"))
assert_true(html.contains("no input is matched or parsed"))
}pub struct AnimatedRenderer {
plan : MotionPlan?
playback : PlaybackPlan?
svg : SvgRenderer
limits : Limits
query_limits : Limits
sequence_view_id : String?
output_units : Int
}impl Renderer for AnimatedRendererfn AnimatedRenderer::new(plan? : MotionPlan, playback? : PlaybackPlan, svg? : SvgRenderer, limits? : Limits, query_limits? : Limits, sequence_view_id? : String, output_units? : Int) -> AnimatedRenderer