journalmap 0.1.0

Journaling datatypes for easy undo, redo & version control
Documentation
use journalmap::JournalVec;

#[cfg(feature = "serde")]
use serde_json;

#[test]
fn test_vec_compat() {
    let mut rsvp: JournalVec<_, ()> = JournalVec::new();

    rsvp.push("Sarah");
    rsvp.push("John");
    rsvp.push("Mariah");
    rsvp.insert(1, "Steve");

    assert_eq!(rsvp[0], "Sarah");
    assert_eq!(rsvp[1], "Steve");
    assert_eq!(rsvp.get(2), Some(&"John"));
    assert_eq!(rsvp.pop(), Some("Mariah"));
    assert_eq!(rsvp.remove(1), Some("Steve"));

    assert_eq!(rsvp[1], "John");
    assert_eq!(rsvp.get(2), None);

    assert_eq!(rsvp.as_slice(), &["Sarah", "John"]);

    rsvp.clear();
    assert_eq!(rsvp.len(), 0);
}

#[cfg(feature = "serde")]
#[test]
fn test_serialize_deserialize() {
    let mut rsvp: JournalVec<String, String> = JournalVec::new();

    rsvp.append_tag("start".to_string()).unwrap();

    rsvp.push("Sarah".to_string());
    rsvp.push("John".to_string());
    rsvp.push("Mariah".to_string());
    rsvp.insert(1, "Steve".to_string());

    rsvp.append_tag("middle".to_string()).unwrap();

    rsvp.pop();
    rsvp.remove(1);

    rsvp.append_tag("end".to_string()).unwrap();

    rsvp.reverse_to_next();

    let journal_1 = rsvp.generate_journal(false);
    let journal_2 = rsvp.generate_journal(true);

    let json_1 = serde_json::to_string(&journal_1).unwrap();
    let json_2 = serde_json::to_string(&journal_2).unwrap();

    let deserialized_rsvp_1: JournalVec<String, String> =
        JournalVec::from_journal(&serde_json::from_str(&json_1).unwrap());
    let deserialized_rsvp_2: JournalVec<String, String> =
        JournalVec::from_journal(&serde_json::from_str(&json_2).unwrap());

    assert_ne!(rsvp.as_slice(), deserialized_rsvp_1.as_slice());
    assert_eq!(rsvp.as_slice(), deserialized_rsvp_2.as_slice());
    rsvp.forward_to_next();
    assert_eq!(rsvp.as_slice(), deserialized_rsvp_1.as_slice());
    assert_ne!(rsvp.as_slice(), deserialized_rsvp_2.as_slice());
}

#[test]
fn test_tag_reverse() {
    let mut rsvp: JournalVec<&'static str, _> = JournalVec::new();

    rsvp.append_tag("start").unwrap();

    rsvp.push("Sarah");
    rsvp.push("John");
    rsvp.push("Mariah");
    rsvp.insert(1, "Steve");

    rsvp.append_tag("middle").unwrap();

    rsvp.pop();
    rsvp.remove(1);

    rsvp.append_tag("end").unwrap();
    rsvp.append_tag("end").unwrap_err();

    assert_eq!(rsvp.reverse_to_tag(&"middle"), true);

    assert_eq!(rsvp.as_slice(), &["Sarah", "Steve", "John", "Mariah"]);

    rsvp.push("Omar");
    rsvp.append_tag("end").unwrap();

    assert_eq!(
        rsvp.as_slice(),
        &["Sarah", "Steve", "John", "Mariah", "Omar"]
    );

    assert_eq!(rsvp.reverse_to_next(), true);
    assert_eq!(rsvp.as_slice(), &["Sarah", "Steve", "John", "Mariah"]);

    assert_eq!(rsvp.reverse_to_next(), true);

    assert_eq!(rsvp.as_slice().len(), 0);
    assert_eq!(rsvp.reverse_to_next(), false);
}

#[test]
fn test_tag_forward() {
    let mut rsvp: JournalVec<&'static str, _> = JournalVec::new();

    rsvp.append_tag("start").unwrap();

    rsvp.push("Sarah");
    rsvp.push("John");
    rsvp.push("Mariah");
    rsvp.insert(1, "Steve");

    rsvp.append_tag("middle").unwrap();

    rsvp.pop();
    rsvp.remove(1);

    rsvp.append_tag("end").unwrap();

    rsvp.reverse_to_next();

    assert_eq!(rsvp.as_slice(), &["Sarah", "Steve", "John", "Mariah"]);

    assert_eq!(rsvp.forward_to_tag(&"end"), true);

    assert_eq!(rsvp.as_slice(), &["Sarah", "John"]);

    rsvp.reverse_to_next();

    rsvp.push("Omar");
    rsvp.append_tag("end").unwrap();

    assert_eq!(
        rsvp.as_slice(),
        &["Sarah", "Steve", "John", "Mariah", "Omar"]
    );

    rsvp.reverse_to_next();
    rsvp.reverse_to_next();

    assert_eq!(rsvp.as_slice().len(), 0);

    assert_eq!(rsvp.forward_to_next(), true);

    assert_eq!(rsvp.as_slice(), &["Sarah", "Steve", "John", "Mariah"]);
}