Integrate release recovery, semantic review, coverage and Windows packaging
This commit is contained in:
@@ -89,6 +89,153 @@ fn assert_source_model_agree(app: &App) {
|
||||
assert!(!app.source_dirty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn state_diagram_routes_constructor_and_source_open_to_the_existing_workspace_without_edits() {
|
||||
let mut f = fixture();
|
||||
let diagram = create_view(&mut f).diagram;
|
||||
let project = f.app.project().clone();
|
||||
let app = App::with_project(project.clone());
|
||||
assert_eq!(app.page, Page::Behavior);
|
||||
assert_eq!(app.state_context().unwrap().diagram, diagram);
|
||||
assert_eq!(behavior::selected_owner(&app), Some(f.machine));
|
||||
assert_eq!(app.behavior.diagram.tool, Tool::Select);
|
||||
assert_eq!(app.selected, project.id);
|
||||
assert_eq!(app.project(), &project);
|
||||
assert!(!app.document.can_undo());
|
||||
|
||||
let directory = tempfile::tempdir().unwrap();
|
||||
let path = directory.path().join("state-view.arcadia");
|
||||
let text = format!(
|
||||
"// Exact authored source must remain unchanged.\n{}",
|
||||
language::format(&project)
|
||||
);
|
||||
std::fs::write(&path, &text).unwrap();
|
||||
let mut reopened = App::with_project(Project::empty());
|
||||
send(
|
||||
&mut reopened,
|
||||
Message::Loaded(Ok(Some(read_snapshot(path.clone()).unwrap()))),
|
||||
);
|
||||
assert_eq!(reopened.page, Page::Behavior);
|
||||
assert_eq!(reopened.state_context().unwrap().diagram, diagram);
|
||||
assert_eq!(reopened.project(), &project);
|
||||
assert_eq!(
|
||||
reopened.document.bundle().files[&reopened.document.bundle().entry],
|
||||
text
|
||||
);
|
||||
assert_eq!(std::fs::read_to_string(path).unwrap(), text);
|
||||
assert!(!reopened.document.can_undo());
|
||||
assert_source_model_agree(&reopened);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn state_diagram_routes_picker_and_reveal_but_explicit_architecture_does_not_bounce() {
|
||||
let mut f = fixture();
|
||||
let diagram = create_view(&mut f).diagram;
|
||||
let mut project = f.app.project().clone();
|
||||
let second = state_edit::create_view(&project, f.machine).unwrap();
|
||||
project = prepare_command(&project, &second.command).unwrap().project;
|
||||
let transition = project.relate(RelationKind::StateTransition, "Switch", f.a, f.b);
|
||||
let mut app = App::with_project(project.clone());
|
||||
let before = app.document.snapshot();
|
||||
send(&mut app, Message::Page(Page::Diagram));
|
||||
assert_eq!(app.page, Page::Diagram);
|
||||
assert_eq!(app.active_diagram, None);
|
||||
send(
|
||||
&mut app,
|
||||
Message::Diagram(Choice {
|
||||
id: second.diagram,
|
||||
label: "Second state view".into(),
|
||||
}),
|
||||
);
|
||||
assert_eq!(app.page, Page::Behavior);
|
||||
assert_eq!(app.state_context().unwrap().diagram, second.diagram);
|
||||
send(&mut app, Message::RevealInDiagram(diagram, transition));
|
||||
assert_eq!(app.page, Page::Behavior);
|
||||
assert_eq!(app.state_context().unwrap().diagram, diagram);
|
||||
assert_eq!(app.selected, transition);
|
||||
assert_eq!(app.draft.as_ref().unwrap().original, transition);
|
||||
assert!(Arc::ptr_eq(&before, &app.document.snapshot()));
|
||||
assert_source_model_agree(&app);
|
||||
|
||||
let architecture = project.ensure_diagram(Layer::Sa);
|
||||
let mut app = App::with_project(project);
|
||||
send(
|
||||
&mut app,
|
||||
Message::Diagram(Choice {
|
||||
id: diagram,
|
||||
label: "State view".into(),
|
||||
}),
|
||||
);
|
||||
assert_eq!(app.page, Page::Behavior);
|
||||
send(&mut app, Message::Page(Page::Diagram));
|
||||
assert_eq!(app.page, Page::Diagram);
|
||||
assert_eq!(app.active_diagram, Some(architecture));
|
||||
assert!(app.state_context().is_none());
|
||||
assert!(!app.document.can_undo());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn state_diagram_routes_preserve_selected_raw_properties_and_pending_behavior_guards() {
|
||||
let mut f = fixture();
|
||||
let diagram = create_view(&mut f).diagram;
|
||||
let mut app = App::with_project(f.app.project().clone());
|
||||
send(&mut app, Message::Select(f.a));
|
||||
send(
|
||||
&mut app,
|
||||
Message::Field("/alias".into(), "invalid alias!".into()),
|
||||
);
|
||||
let raw = serde_json::to_value(app.draft.as_ref().unwrap().recovery_snapshot()).unwrap();
|
||||
assert!(!app.apply());
|
||||
let before = app.document.snapshot();
|
||||
// Exercise normalization itself with an existing raw draft, including callers
|
||||
// that have just adopted a view without a successful property Apply.
|
||||
app.page = Page::Diagram;
|
||||
app.route_state_diagram_workspace();
|
||||
assert_eq!(app.page, Page::Behavior);
|
||||
assert_eq!(app.selected, f.a);
|
||||
assert_eq!(
|
||||
serde_json::to_value(app.draft.as_ref().unwrap().recovery_snapshot()).unwrap(),
|
||||
raw
|
||||
);
|
||||
assert!(Arc::ptr_eq(&before, &app.document.snapshot()));
|
||||
send(
|
||||
&mut app,
|
||||
Message::Diagram(Choice {
|
||||
id: diagram,
|
||||
label: "State view".into(),
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_value(app.draft.as_ref().unwrap().recovery_snapshot()).unwrap(),
|
||||
raw
|
||||
);
|
||||
assert!(Arc::ptr_eq(&before, &app.document.snapshot()));
|
||||
|
||||
let mut app = App::with_project(f.app.project().clone());
|
||||
form(
|
||||
&mut app,
|
||||
states::Event::Start(f.machine, states::Tool::Transition, f.a),
|
||||
);
|
||||
form(
|
||||
&mut app,
|
||||
states::Event::Name("Pending behavior stays".into()),
|
||||
);
|
||||
let pending = app.behavior.recovery_snapshot().unwrap();
|
||||
let context = app.state_context().unwrap();
|
||||
send(&mut app, Message::Page(Page::Diagram));
|
||||
send(
|
||||
&mut app,
|
||||
Message::Diagram(Choice {
|
||||
id: diagram,
|
||||
label: "State view".into(),
|
||||
}),
|
||||
);
|
||||
assert_eq!(app.page, Page::Behavior);
|
||||
assert_eq!(app.state_context().unwrap().diagram, context.diagram);
|
||||
assert_eq!(app.behavior.recovery_snapshot().unwrap(), pending);
|
||||
assert!(!app.document.can_undo());
|
||||
}
|
||||
|
||||
struct NavigationFixture {
|
||||
app: App,
|
||||
machine_a: Id,
|
||||
@@ -789,12 +936,15 @@ fn fallback_owner_first_selection_keeps_the_captured_context_for_its_first_move(
|
||||
let f = fixture();
|
||||
let mut project = f.app.project().clone();
|
||||
// One eligible machine makes the fallback deterministic. Start from a loaded
|
||||
// project with no selected behavior element and no explicitly chosen owner.
|
||||
// architecture view with no selected behavior element or chosen owner. A
|
||||
// state-only project now opens its saved view with an explicit owner.
|
||||
project
|
||||
.elements
|
||||
.retain(|id, element| f.members.contains(id) || element.kind() == Kind::System);
|
||||
let plan = state_edit::create_view(&project, f.machine).unwrap();
|
||||
let project = prepare_command(&project, &plan.command).unwrap().project;
|
||||
let mut project = prepare_command(&project, &plan.command).unwrap().project;
|
||||
let architecture = project.ensure_diagram(Layer::Sa);
|
||||
project.diagrams.get_mut(&architecture).unwrap().projection = ProjectionKind::Allocation;
|
||||
let mut app = App::with_project(project);
|
||||
assert_eq!(app.selected, app.project().id);
|
||||
assert!(app.behavior.active_owner.is_none());
|
||||
@@ -917,7 +1067,11 @@ fn shared_semantic_states_keep_architecture_and_behavior_placements_independent(
|
||||
id: architecture,
|
||||
label: app.project().named(architecture).into(),
|
||||
};
|
||||
// The initial UUID-ordered view may be a state view, which correctly opens
|
||||
// Behavior. Enter Architecture explicitly before testing its selection.
|
||||
send(&mut app, Message::Page(Page::Diagram));
|
||||
send(&mut app, Message::Diagram(architecture_choice));
|
||||
assert_eq!(app.page, Page::Diagram);
|
||||
send(&mut app, Message::Select(f.b));
|
||||
assert_eq!(app.active_diagram, Some(architecture));
|
||||
assert_eq!(app.selected_node, Some(arch_b));
|
||||
|
||||
Reference in New Issue
Block a user