sim-table-fs 0.1.3

SIM workspace package for sim table fs.
Documentation
use super::support::*;

#[test]
fn del_requires_read_before_returning_removed_value() {
    let mut cx = cx();
    grant(&mut cx, &[table_fs_write_capability()]);
    let root = test_root("del-write-only");
    let dir = FsDir::open(root.clone()).unwrap();
    std::fs::write(root.join("note.siml"), "\"secret\"").unwrap();

    let err = dir.del(&mut cx, Symbol::new("note")).unwrap_err();

    assert!(matches!(
        err,
        sim_kernel::Error::CapabilityDenied { capability }
            if capability == table_fs_read_capability()
    ));
    assert!(root.join("note.siml").exists());
}

#[test]
fn del_decode_error_leaves_file_in_place() {
    let mut cx = cx();
    grant(
        &mut cx,
        &[table_fs_read_capability(), table_fs_write_capability()],
    );
    let root = test_root("del-bad-codec");
    let dir = FsDir::open(root.clone()).unwrap();
    std::fs::write(root.join("bad.siml"), "(").unwrap();

    dir.del(&mut cx, Symbol::new("bad")).unwrap_err();

    assert!(root.join("bad.siml").exists());
}

#[test]
fn dir_edit_round_trips_with_fs_write() {
    let mut cx = cx();
    grant_edit_authority(&mut cx);
    let root = test_root("dir-edit-roundtrip");
    let dir = FsDir::open(root.clone()).unwrap();
    write_value_with_codec(
        &mut cx,
        &root.join("note.siml"),
        Symbol::qualified("codec", "lisp"),
        "alpha beta",
    );

    dir.edit(&mut cx, Symbol::new("note"), "beta", "gamma", false)
        .unwrap();

    let value = dir.get(&mut cx, Symbol::new("note")).unwrap();
    assert_eq!(
        value.object().as_expr(&mut cx).unwrap(),
        Expr::String("alpha gamma".to_owned())
    );
}

#[test]
fn dir_edit_lines_round_trips_with_fs_write() {
    let mut cx = cx();
    grant_edit_authority(&mut cx);
    let root = test_root("dir-edit-lines");
    let dir = FsDir::open(root.clone()).unwrap();
    write_value_with_codec(
        &mut cx,
        &root.join("note.siml"),
        Symbol::qualified("codec", "lisp"),
        "a\nb\nc\n",
    );

    dir.edit_lines(&mut cx, Symbol::new("note"), 2, 2, "B\n")
        .unwrap();

    let value = dir.get(&mut cx, Symbol::new("note")).unwrap();
    assert_eq!(
        value.object().as_expr(&mut cx).unwrap(),
        Expr::String("a\nB\nc\n".to_owned())
    );
}

#[test]
fn dir_edit_is_atomic_on_failure() {
    let mut cx = cx();
    grant_edit_authority(&mut cx);
    let root = test_root("dir-edit-atomic");
    let dir = FsDir::open(root.clone()).unwrap();
    let path = root.join("note.siml");
    write_value_with_codec(
        &mut cx,
        &path,
        Symbol::qualified("codec", "lisp"),
        "alpha beta",
    );
    let before = std::fs::read_to_string(&path).unwrap();

    let err = dir
        .edit(&mut cx, Symbol::new("note"), "missing", "gamma", false)
        .unwrap_err();

    assert!(err.to_string().contains("pattern not found"));
    assert_eq!(std::fs::read_to_string(path).unwrap(), before);
}

#[test]
fn dir_edit_requires_edit_capability() {
    let mut cx = cx();
    grant(
        &mut cx,
        &[table_fs_read_capability(), table_fs_write_capability()],
    );
    let root = test_root("dir-edit-cap");
    let dir = FsDir::open(root.clone()).unwrap();
    let path = root.join("note.siml");
    write_value_with_codec(
        &mut cx,
        &path,
        Symbol::qualified("codec", "lisp"),
        "alpha beta",
    );

    let err = dir
        .edit(&mut cx, Symbol::new("note"), "beta", "gamma", false)
        .unwrap_err();

    assert!(matches!(
        err,
        sim_kernel::Error::CapabilityDenied { capability }
            if capability == table_fs_edit_capability()
    ));
    let value = dir.get(&mut cx, Symbol::new("note")).unwrap();
    assert_eq!(
        value.object().as_expr(&mut cx).unwrap(),
        Expr::String("alpha beta".to_owned())
    );
}

#[test]
fn dir_edit_requires_write_capability() {
    let mut cx = cx();
    grant(
        &mut cx,
        &[table_fs_read_capability(), table_fs_edit_capability()],
    );
    let root = test_root("dir-edit-write-cap");
    let dir = FsDir::open(root.clone()).unwrap();
    write_value_with_codec(
        &mut cx,
        &root.join("note.siml"),
        Symbol::qualified("codec", "lisp"),
        "alpha beta",
    );

    let err = dir
        .edit(&mut cx, Symbol::new("note"), "beta", "gamma", false)
        .unwrap_err();

    assert!(matches!(
        err,
        sim_kernel::Error::CapabilityDenied { capability }
            if capability == table_fs_write_capability()
    ));
}