oas-document 1.1.1

OAS Identity Document types and validation for the Open Agent Specification
Documentation
// Property-based tests for document serialization round-trips.

use proptest::prelude::*;

proptest! {
    /// Documents created via the builder always serialize/deserialize cleanly.
    #[test]
    fn builder_document_serde_round_trip(
        ns in "[a-z][a-z0-9]{0,5}",
        ident in "[a-zA-Z0-9][a-zA-Z0-9._-]{0,10}",
    ) {
        let did = format!("did:oas:{ns}:hmr:{ident}");
        let kp = oas_crypto::keypair::OasKeyPair::generate();
        let doc = oas_document::builder::DocumentBuilder::new(&did, "hmr")
            .conformance_level(oas_document::conformance::ConformanceLevel::L0)
            .add_verification_method(&kp)
            .build_and_sign(&kp, "2026-01-15T00:00:00Z");

        if let Ok(doc) = doc {
            let json = serde_json::to_string(&doc);
            prop_assert!(json.is_ok(), "serialize failed");

            let json = json.unwrap_or_default();
            let deser: Result<oas_document::OasDocument, _> = serde_json::from_str(&json);
            prop_assert!(deser.is_ok(), "deserialize failed: {json}");

            let deser = deser.unwrap_or_else(|_| doc.clone());
            prop_assert_eq!(&doc.id, &deser.id);
            prop_assert_eq!(&doc.kind, &deser.kind);
        }
    }

    /// Conformance level round-trips through serde.
    #[test]
    fn conformance_level_serde_round_trip(
        level in prop_oneof![
            Just(oas_document::conformance::ConformanceLevel::L0),
            Just(oas_document::conformance::ConformanceLevel::L1),
            Just(oas_document::conformance::ConformanceLevel::L2),
        ]
    ) {
        let json = serde_json::to_string(&level);
        prop_assert!(json.is_ok());
        let deser: Result<oas_document::conformance::ConformanceLevel, _> =
            serde_json::from_str(&json.unwrap_or_default());
        prop_assert!(deser.is_ok());
        prop_assert_eq!(level, deser.unwrap_or(oas_document::conformance::ConformanceLevel::L0));
    }

    /// Lifecycle status round-trips through string conversion.
    #[test]
    fn lifecycle_status_round_trip(
        status in prop_oneof![
            Just("nascent"),
            Just("active"),
            Just("dormant"),
            Just("suspended"),
            Just("terminated"),
            Just("archived"),
        ]
    ) {
        let parsed: Result<oas_document::lifecycle::LifecycleStatus, _> = status.parse();
        prop_assert!(parsed.is_ok(), "parse failed for {status}");
    }
}