cartulary 0.3.0-alpha.1

The knowledge layer of your project — decisions, issues, docs, all in one place.
Documentation
mod collection;
pub mod dr_status;
pub mod edit;
pub mod finding;
pub mod record_link;
pub mod transition;
mod value;

pub use collection::DecisionRecordCollection;
pub use dr_status::DrStatus;
pub use edit::{apply_edit, apply_edits, DecisionRecordEdit};
pub use finding::DecisionRecordFinding;
pub use record_link::{RecordLink, RecordLinks, Relationship};
pub use transition::{CascadeAction, CascadeRequest, TransitionError, TransitionOutcome};
pub use value::DecisionRecord;

/// Re-export the unified `Event` and `EventLog` types.
pub use crate::domain::model::event::Event;
pub use crate::domain::model::event::EventLog;

#[cfg(test)]
pub mod strategy {
    use super::dr_status::strategy::dr_status;
    use super::*;
    use crate::domain::model::body::strategy::arb_body;
    use crate::domain::model::entry_locator::EntryLocator;
    use crate::domain::model::entry_origin::EntryOrigin;
    use crate::domain::model::record_kind::strategy::record_kind;
    use crate::domain::model::record_ref::strategy::decision_record_ref;
    use crate::domain::model::temporal::iso_date::strategy::iso_date;
    use crate::domain::model::title::strategy::arb_title;
    use proptest::prelude::*;

    /// Optional one-line descriptions backed by the [`Description`]
    /// strategy.
    pub fn arb_description(
    ) -> impl Strategy<Value = Option<crate::domain::model::description::Description>> {
        proptest::option::of(crate::domain::model::description::strategy::arb_description())
    }

    pub fn decision_record() -> impl Strategy<Value = DecisionRecord> {
        (
            decision_record_ref(),
            record_kind(),
            arb_title(),
            arb_description(),
            dr_status(),
            iso_date(),
            crate::domain::model::tag_list::strategy::tag_list(),
            arb_body(),
            crate::domain::model::event::strategy::event_log(),
        )
            .prop_map(
                |(id, kind, title, description, status, date, tags, content, events)| {
                    DecisionRecord {
                        id,
                        kind,
                        title,
                        description,
                        status,
                        date,
                        tags,
                        aliases: Vec::new(),
                        content,
                        events,
                        links: RecordLinks::new(),
                        relates: crate::domain::model::relates::Relates::default(),
                        origin: EntryOrigin::Local,
                        location: EntryLocator::default(),
                    }
                },
            )
    }
}

#[cfg(test)]
mod tests {
    use super::strategy::decision_record;
    use proptest::prelude::*;

    proptest! {
        #[test]
        fn decision_record_clone_equals_original(record in decision_record()) {
            prop_assert_eq!(record.clone(), record);
        }

        #[test]
        fn decision_record_id_is_positive(record in decision_record()) {
            prop_assert!(record.id.numeric_id() > 0);
        }

        #[test]
        fn decision_record_kind_is_valid(record in decision_record()) {
            let s = record.kind.as_str();
            prop_assert!(!s.is_empty());
            prop_assert!(s.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-'));
        }
    }
}