ifc-classification 0.4.0

Classification systems, document references, libraries, external references.
Documentation
//! Generic external-reference relationship authoring and validation tests.

use ifc_classification::{
    create_external_reference_relationship, ClassificationError, ClassificationView,
    ExternalReferenceRelationshipDraft,
};
use ifc_model::{Entity, Model, Transaction, Value};

fn text(value: &str) -> Value {
    Value::Text(value.into())
}

#[test]
fn schema_pins_external_reference_relationship_slots() {
    assert_eq!(
        ifc_schema::ifc4().attribute_names("IFCEXTERNALREFERENCERELATIONSHIP"),
        [
            "Name",
            "Description",
            "RelatingReference",
            "RelatedResourceObjects"
        ]
    );
}

#[test]
fn authored_relationship_round_trips_and_queries_by_resource() {
    let mut model = Model::new();
    let reference = model.push(Entity::new(
        "IFCCLASSIFICATIONREFERENCE",
        vec![
            text("uri"),
            text("id"),
            Value::Null,
            Value::Null,
            Value::Null,
            Value::Null,
        ],
    ));
    let approval = model.push(Entity::new(
        "IFCAPPROVAL",
        vec![
            text("A"),
            Value::Null,
            Value::Null,
            Value::Null,
            Value::Null,
            Value::Null,
            Value::Null,
            Value::Null,
            Value::Null,
        ],
    ));
    let mut tx = Transaction::new(&model);
    let relation = create_external_reference_relationship(
        &mut tx,
        &model,
        ExternalReferenceRelationshipDraft::new(reference, &[approval]).name("evidence"),
    )
    .unwrap();
    tx.commit(&mut model).unwrap();

    let view = ClassificationView::new(&model);
    let projected = view.external_reference_relationship(relation).unwrap();
    assert_eq!(projected.name().unwrap(), Some("evidence"));
    assert_eq!(projected.relating_reference().unwrap(), reference);
    assert_eq!(projected.related_resources().unwrap(), [approval]);
    assert_eq!(
        view.external_references_for(approval)
            .unwrap()
            .into_iter()
            .map(|item| item.id())
            .collect::<Vec<_>>(),
        [relation]
    );
}

#[test]
fn invalid_selects_and_malformed_sets_are_refused() {
    let mut model = Model::new();
    let wall = model.push(Entity::new("IFCWALL", vec![]));
    let person = model.push(Entity::new("IFCPERSON", vec![]));
    let reference = model.push(Entity::new(
        "IFCDOCUMENTREFERENCE",
        vec![
            text("uri"),
            text("id"),
            Value::Null,
            Value::Null,
            Value::Null,
        ],
    ));
    let mut tx = Transaction::new(&model);
    let before = tx.len();
    assert!(matches!(
        create_external_reference_relationship(
            &mut tx,
            &model,
            ExternalReferenceRelationshipDraft::new(reference, &[wall])
        ),
        Err(ClassificationError::AuthoringReferenceType { target, .. }) if target == wall
    ));
    assert_eq!(tx.len(), before);
    assert!(matches!(
        create_external_reference_relationship(
            &mut tx,
            &model,
            ExternalReferenceRelationshipDraft::new(reference, &[person, person])
        ),
        Err(ClassificationError::AuthoringInvalid {
            attribute: "RelatedResourceObjects",
            ..
        })
    ));
    assert_eq!(tx.len(), before);

    let malformed = model.push(Entity::new(
        "IFCEXTERNALREFERENCERELATIONSHIP",
        vec![
            Value::Null,
            Value::Null,
            Value::Ref(reference),
            Value::List(vec![Value::Ref(wall)]),
        ],
    ));
    assert!(matches!(
        ClassificationView::new(&model).external_reference_relationship(malformed),
        Err(ClassificationError::ReferenceType { target, .. }) if target == wall
    ));
}