summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatěj Laitl <matej@laitl.cz>2019-03-07 19:01:52 +0100
committerMatěj Laitl <matej@laitl.cz>2019-03-07 19:04:40 +0100
commit3387ec4bd0cab2b6d888b663fbd88c5cdc00ba95 (patch)
tree5ac9372007163d8f4a6def66ce031bfbaa129bae
parent80ab26aadad2997b1cfc48bd9b580f0be1ac02ec (diff)
Make Component serialization deterministic, add integration tests
Just swap HashMap for BTreeMap, which has defined iteration order (also organizes elements by key ordering, rather than hash -- strings support both). This allows us to write integration tests, so here they are. Fixes #7.
-rw-r--r--src/components.rs12
-rw-r--r--tests/calendar.rs41
2 files changed, 47 insertions, 6 deletions
diff --git a/src/components.rs b/src/components.rs
index d8f6c8e..b4efb91 100644
--- a/src/components.rs
+++ b/src/components.rs
@@ -4,7 +4,7 @@ use uuid::Uuid;
// use std::io;
use std::fmt;
use std::mem;
-use std::collections::HashMap;
+use std::collections::BTreeMap;
use crate::properties::*;
@@ -18,7 +18,7 @@ pub struct Todo { inner: InnerComponent }
#[derive(Debug, Default)]
struct InnerComponent{
- properties: HashMap<String,Property>,
+ properties: BTreeMap<String, Property>,
multi_properties: Vec<Property>
}
@@ -27,7 +27,7 @@ impl InnerComponent {
/// copies over everything
pub fn done(&mut self) -> Self {
InnerComponent{
- properties: mem::replace(&mut self.properties, HashMap::new()),
+ properties: mem::replace(&mut self.properties, BTreeMap::new()),
multi_properties: mem::replace(&mut self.multi_properties, Vec::new()),
}
}
@@ -116,8 +116,8 @@ pub trait Component {
/// These are used in the `BEGIN` and `END` line of the component.
fn component_kind() -> &'static str;
- /// Allows access to the inner properties HashMap.
- fn properties(&self) -> &HashMap<String,Property>;
+ /// Allows access to the inner properties map.
+ fn properties(&self) -> &BTreeMap<String,Property>;
/// Read-only access to `multi_properties`
fn multi_properties(&self) -> &Vec<Property> ;
@@ -290,7 +290,7 @@ macro_rules! component_impl {
fn component_kind() -> &'static str { $kind }
/// Read-only access to `properties`
- fn properties(&self) -> &HashMap<String, Property> {
+ fn properties(&self) -> &BTreeMap<String, Property> {
&self.inner.properties
}
diff --git a/tests/calendar.rs b/tests/calendar.rs
new file mode 100644
index 0000000..785bec5
--- /dev/null
+++ b/tests/calendar.rs
@@ -0,0 +1,41 @@
+use chrono::prelude::*;
+use icalendar::{Calendar, Class, Component, Event, EventStatus};
+
+const EXPECTED_CAL_CONTENT: &str = "\
+BEGIN:VCALENDAR\r
+VERSION:2.0\r
+PRODID:ICALENDAR-RS\r
+CALSCALE:GREGORIAN\r
+BEGIN:VEVENT\r
+CLASS:CONFIDENTIAL\r
+DESCRIPTION:Description\r
+DTEND:20140709T091011\r
+DTSTAMP:20190307T181159\r
+DTSTART:20140708T091011\r
+LOCATION:Somewhere\r
+PRIORITY:10\r
+STATUS:TENTATIVE\r
+SUMMARY:summary\r
+UID:euid\r
+END:VEVENT\r
+END:VCALENDAR\r
+";
+
+#[test]
+fn test_calendar_to_string() {
+ let mut calendar = Calendar::new();
+ let event = Event::new()
+ .status(EventStatus::Tentative)
+ .starts(Local.ymd(2014, 7, 8).and_hms(9, 10, 11))
+ .ends(Local.ymd(2014, 7, 9).and_hms(9, 10, 11))
+ .priority(11) // converted to 10
+ .summary("summary")
+ .description("Description")
+ .location("Somewhere")
+ .uid("euid")
+ .class(Class::Confidential)
+ .add_property("DTSTAMP", "20190307T181159")
+ .done();
+ calendar.push(event);
+ assert_eq!(calendar.to_string(), EXPECTED_CAL_CONTENT);
+}