157 lines
5.4 KiB
Rust
157 lines
5.4 KiB
Rust
use oa_core::{source_project::*, view_options::*, *};
|
|
|
|
fn fixture(layer: Layer) -> (Project, Id, Id, Id, Id) {
|
|
let mut p = Project::empty();
|
|
let oa = p
|
|
.add_element(Kind::Activity, Layer::Oa, "Assess alarm", None)
|
|
.unwrap();
|
|
let oa2 = p
|
|
.add_element(Kind::Activity, Layer::Oa, "Respond", None)
|
|
.unwrap();
|
|
let sa = p
|
|
.add_element(Kind::Function, Layer::Sa, "Assess alarm", None)
|
|
.unwrap();
|
|
let edge = p.relate(RelationKind::Interaction, "Alarm", oa, oa2);
|
|
let category = p
|
|
.add_element(Kind::ExchangeCategory, Layer::Oa, "Alarm data", None)
|
|
.unwrap();
|
|
*p.elements.get_mut(&category).unwrap().shared_mut().unwrap() = SharedBody::ExchangeCategory {
|
|
family: ExchangeFamily::Work,
|
|
exchanges: vec![edge],
|
|
};
|
|
let context = p
|
|
.add_element(Kind::Process, Layer::Oa, "Alarm handling", None)
|
|
.unwrap();
|
|
let d = p.ensure_diagram(layer);
|
|
p.diagrams.get_mut(&d).unwrap().projection = ProjectionKind::Traceability;
|
|
for (i, element) in [oa, oa2, sa].into_iter().enumerate() {
|
|
p.place(
|
|
d,
|
|
element,
|
|
Position {
|
|
x: 300. * i as f32,
|
|
y: 40.,
|
|
},
|
|
);
|
|
}
|
|
p.diagrams.get_mut(&d).unwrap().view_options = ViewOptions {
|
|
hidden_edges: vec![edge],
|
|
work_categories: CategorySelection::Any(vec![category]),
|
|
work_contexts: ContextSelection::Any(vec![context]),
|
|
..Default::default()
|
|
};
|
|
validate_candidate(&p).unwrap();
|
|
(p, d, oa, sa, category)
|
|
}
|
|
|
|
#[test]
|
|
fn projection_switching_preserves_complete_model_history_and_all_serializations() {
|
|
for layer in [Layer::Oa, Layer::Sa] {
|
|
let (baseline, diagram, _, _, _) = fixture(layer);
|
|
for projection in [
|
|
ProjectionKind::Overview,
|
|
ProjectionKind::Decomposition,
|
|
ProjectionKind::Allocation,
|
|
ProjectionKind::FunctionalDataflow,
|
|
ProjectionKind::Capabilities,
|
|
] {
|
|
let mut expected = baseline.clone();
|
|
expected.diagrams.get_mut(&diagram).unwrap().projection = projection;
|
|
let mut session = Session::new(baseline.clone());
|
|
session
|
|
.execute(Command::EditDiagram(
|
|
diagram,
|
|
expected.diagrams[&diagram].clone(),
|
|
))
|
|
.unwrap();
|
|
assert_eq!(session.project(), &expected);
|
|
let view = projection::project_view(session.project(), diagram);
|
|
assert!(
|
|
view.nodes
|
|
.iter()
|
|
.all(|n| expected.elements[&n.element].layer() == layer)
|
|
);
|
|
assert_eq!(
|
|
view,
|
|
projection::project_view_with_index(&expected, diagram, &ViewIndex::new(&expected))
|
|
);
|
|
let source = language::format(&expected);
|
|
assert_eq!(language::parse(&source).unwrap(), expected);
|
|
assert_eq!(
|
|
persistence::decode(&serde_json::to_vec(&expected).unwrap()).unwrap(),
|
|
expected
|
|
);
|
|
let bundle = format_bundle(&expected);
|
|
assert_eq!(
|
|
compile_bundle(&bundle, ProjectLimits::default())
|
|
.unwrap()
|
|
.decoded
|
|
.project,
|
|
expected
|
|
);
|
|
session.undo();
|
|
assert_eq!(session.project(), &baseline);
|
|
assert!(!session.can_undo());
|
|
session.redo();
|
|
assert_eq!(session.project(), &expected);
|
|
session
|
|
.execute(Command::EditDiagram(
|
|
diagram,
|
|
baseline.diagrams[&diagram].clone(),
|
|
))
|
|
.unwrap();
|
|
assert_eq!(session.project(), &baseline);
|
|
assert_eq!(
|
|
projection::project_view(session.project(), diagram),
|
|
projection::project_view(&baseline, diagram)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn projection_switching_does_not_admit_missing_elements_or_invalid_filter_kinds() {
|
|
let (mut p, d, oa, _, category) = fixture(Layer::Sa);
|
|
p.diagrams.get_mut(&d).unwrap().projection = ProjectionKind::Allocation;
|
|
validate_candidate(&p).unwrap();
|
|
let valid = p.clone();
|
|
let node = p.diagrams[&d]
|
|
.nodes
|
|
.values()
|
|
.find(|n| n.element == oa)
|
|
.unwrap()
|
|
.id;
|
|
p.diagrams
|
|
.get_mut(&d)
|
|
.unwrap()
|
|
.nodes
|
|
.get_mut(&node)
|
|
.unwrap()
|
|
.element = Id::new_v4();
|
|
assert!(validate_candidate(&p).is_err());
|
|
p = valid.clone();
|
|
p.diagrams.get_mut(&d).unwrap().view_options.work_categories = CategorySelection::Any(vec![oa]);
|
|
assert!(validate_candidate(&p).is_err());
|
|
p = valid;
|
|
p.elements.remove(&category);
|
|
assert!(validate_candidate(&p).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn projection_switching_keeps_typed_state_membership_strict() {
|
|
let (mut p, d, _, _, _) = fixture(Layer::Sa);
|
|
let system = p
|
|
.add_element(Kind::System, Layer::Sa, "System", None)
|
|
.unwrap();
|
|
let machine = p
|
|
.add_element(Kind::StateMachine, Layer::Sa, "Modes", Some(system))
|
|
.unwrap();
|
|
p.diagrams.get_mut(&d).unwrap().projection = ProjectionKind::StateMachine { machine };
|
|
assert!(
|
|
validation::validate(&p)
|
|
.iter()
|
|
.any(|i| i.code == "state_diagram_member")
|
|
);
|
|
assert!(validate_candidate(&p).is_err());
|
|
}
|