journalmap 0.1.1

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

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

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

    rsvp.insert("Sarah");
    rsvp.insert("John");
    rsvp.insert("Mariah");

    assert_eq!(rsvp.contains(&"Sarah"), true);
    assert_eq!(rsvp.contains(&"John"), true);
    assert_eq!(rsvp.contains(&"Mariah"), true);
    assert_eq!(rsvp.contains(&"James"), false);

    assert_eq!(rsvp.remove("John"), true);
    assert_eq!(rsvp.remove("John"), false);

    assert_eq!(rsvp.contains(&"John"), false);

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

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

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

    rsvp.insert("Sarah".to_string());
    rsvp.insert("John".to_string());
    rsvp.insert("Mariah".to_string());

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

    rsvp.remove("Mariah".to_string());
    rsvp.insert("Ken".to_string());

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

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

    let json_1 = serde_json::to_string(&rsvp.generate_journal(false)).unwrap();
    let json_2 = serde_json::to_string(&rsvp.generate_journal(true)).unwrap();

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

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

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

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

    rsvp.insert("Sarah");
    rsvp.insert("John");
    rsvp.insert("Mariah");

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

    rsvp.remove("Mariah");
    rsvp.insert("Ken");

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

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

    assert_eq!(rsvp.contains(&"Sarah"), true);
    assert_eq!(rsvp.contains(&"John"), true);
    assert_eq!(rsvp.contains(&"Mariah"), true);
    assert_eq!(rsvp.contains(&"Ken"), false);

    rsvp.insert("Omar");

    rsvp.append_tag("end").unwrap();
    assert_eq!(rsvp.current_tag(), Some(&"end"));

    assert_eq!(rsvp.contains(&"Sarah"), true);
    assert_eq!(rsvp.contains(&"John"), true);
    assert_eq!(rsvp.contains(&"Mariah"), true);
    assert_eq!(rsvp.contains(&"Ken"), false);
    assert_eq!(rsvp.contains(&"Omar"), true);

    assert_eq!(rsvp.reverse_to_next(), true);
    assert_eq!(rsvp.current_tag(), Some(&"middle"));

    assert_eq!(rsvp.reverse_to_next(), true);
    assert_eq!(rsvp.current_tag(), Some(&"start"));

    assert_eq!(rsvp.len(), 0);
    assert_eq!(rsvp.reverse_to_next(), false);
    assert_eq!(rsvp.current_tag(), Some(&"start"));
}

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

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

    rsvp.insert("Sarah");
    rsvp.insert("John");
    rsvp.insert("Mariah");

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

    rsvp.remove("Mariah");
    rsvp.insert("Ken");

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

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

    assert_eq!(rsvp.contains(&"Sarah"), true);
    assert_eq!(rsvp.contains(&"John"), true);
    assert_eq!(rsvp.contains(&"Mariah"), true);
    assert_eq!(rsvp.contains(&"Ken"), false);

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

    assert_eq!(rsvp.contains(&"Sarah"), true);
    assert_eq!(rsvp.contains(&"John"), true);
    assert_eq!(rsvp.contains(&"Mariah"), false);
    assert_eq!(rsvp.contains(&"Ken"), true);

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

    rsvp.insert("Omar");

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

    assert_eq!(rsvp.contains(&"Sarah"), true);
    assert_eq!(rsvp.contains(&"John"), true);
    assert_eq!(rsvp.contains(&"Mariah"), true);
    assert_eq!(rsvp.contains(&"Ken"), false);
    assert_eq!(rsvp.contains(&"Omar"), true);

    assert_eq!(rsvp.forward_to_next(), false);
}

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

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

    rsvp.retain_tags(|tag| tag != &"middle");

    rsvp.reverse_to_next();

    assert_eq!(rsvp.current_tag(), Some(&"end"));

    rsvp.reverse_to_next();

    assert_eq!(rsvp.current_tag(), Some(&"start"));
}