lemma-engine 0.8.13

A language that means business.
Documentation
use crate::parsing::ast::DataValue;
use crate::parsing::parse;

#[test]
fn test_parse_with_spec_reference() {
    let input = r#"spec person
data name: "John"
uses contract: employment_contract"#;
    let result = parse(
        input,
        crate::parsing::source::SourceType::Volatile,
        &crate::ResourceLimits::default(),
    )
    .unwrap()
    .into_flattened_specs();
    assert_eq!(result.len(), 1);
    assert_eq!(result[0].data.len(), 2);

    assert_eq!(
        result[0].data[1].reference,
        crate::parsing::ast::Reference::local("contract".to_string())
    );
    if let DataValue::Import(spec_ref) = &result[0].data[1].value {
        assert_eq!(spec_ref.name, "employment_contract");
        assert!(spec_ref.repository.is_none());
    } else {
        panic!("Expected Import");
    }
}

#[test]
fn test_parse_with_and_data_bindings() {
    let input = r#"spec person
uses contract: employment_contract
data contract.start_date: 2024-02-01
data contract.end_date: date
data contract.employment_type: "contractor"
uses base: base_contract"#;
    let result = parse(
        input,
        crate::parsing::source::SourceType::Volatile,
        &crate::ResourceLimits::default(),
    )
    .unwrap()
    .into_flattened_specs();
    assert_eq!(result.len(), 1);
    assert_eq!(result[0].data.len(), 5);

    assert_eq!(
        result[0].data[0].reference,
        crate::parsing::ast::Reference::local("contract".to_string())
    );
    if let DataValue::Import(spec_ref) = &result[0].data[0].value {
        assert_eq!(spec_ref.name, "employment_contract");
        assert!(spec_ref.repository.is_none());
    } else {
        panic!("Expected Import");
    }

    assert_eq!(
        result[0].data[1].reference,
        crate::parsing::ast::Reference::from_path(vec![
            "contract".to_string(),
            "start_date".to_string()
        ])
    );
    match &result[0].data[1].value {
        DataValue::Definition {
            value: Some(lit),
            base: None,
            constraints: None,
            from: None,
        } => {
            assert!(
                matches!(lit, crate::parsing::ast::Value::Date(_)),
                "Expected Date literal"
            );
        }
        _ => panic!("Expected Date literal Definition"),
    }

    assert_eq!(
        result[0].data[2].reference,
        crate::parsing::ast::Reference::from_path(vec![
            "contract".to_string(),
            "end_date".to_string()
        ])
    );
    assert!(
        matches!(
            &result[0].data[2].value,
            DataValue::Definition {
                base: Some(crate::parsing::ast::ParentType::Primitive {
                    primitive: crate::parsing::ast::PrimitiveKind::Date,
                }),
                value: None,
                ..
            }
        ),
        "Expected Definition with date primitive base"
    );

    assert_eq!(
        result[0].data[3].reference,
        crate::parsing::ast::Reference::from_path(vec![
            "contract".to_string(),
            "employment_type".to_string()
        ])
    );
    if let DataValue::Definition {
        value: Some(lit),
        base: None,
        constraints: None,
        from: None,
    } = &result[0].data[3].value
    {
        if let crate::parsing::ast::Value::Text(s) = lit {
            assert_eq!(s, "contractor");
        } else {
            panic!("Expected Text literal");
        }
    } else {
        panic!("Expected literal-only Definition data");
    }

    assert_eq!(
        result[0].data[4].reference,
        crate::parsing::ast::Reference::local("base".to_string())
    );
    if let DataValue::Import(spec_ref) = &result[0].data[4].value {
        assert_eq!(spec_ref.name, "base_contract");
        assert!(spec_ref.repository.is_none());
    } else {
        panic!("Expected Import");
    }
}

#[test]
fn test_data_spec_shorthand_syntax_is_rejected() {
    let input = r#"spec person
data contract: spec employment_contract"#;
    let result = parse(
        input,
        crate::parsing::source::SourceType::Volatile,
        &crate::ResourceLimits::default(),
    );
    assert!(
        result.is_err(),
        "'data ... : spec ...' syntax should be rejected"
    );
}