summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/basic_match.rs92
-rw-r--r--tests/common/mod.rs175
2 files changed, 267 insertions, 0 deletions
diff --git a/tests/basic_match.rs b/tests/basic_match.rs
new file mode 100644
index 0000000..2f65451
--- /dev/null
+++ b/tests/basic_match.rs
@@ -0,0 +1,92 @@
+/*
+ * This file is part of Datafu
+ * Copyright (C) 2021  Soni L.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+extern crate datafu;
+
+mod common;
+
+use common::Value;
+
+#[test]
+fn test_basic_example() {
+    let tree = Value::M(vec![
+        ("foo".into(), Value::U(1)),
+        ("bar".into(), Value::M(vec![
+            ("baz".into(), Value::U(2)),
+        ].into_iter().collect())),
+    ].into_iter().collect());
+    let pat = datafu::Pattern::<Value>::compile("->X:?$dict->Y", None).ok().unwrap();
+    let mut matcher = pat.attempt_match(&tree);
+    let m = matcher.next();
+    // TODO
+    todo!();
+    //assert m['X'][0] == 'bar'
+    //assert m['Y'][0] == 'baz'
+    //assert m['Y'][1] == 2
+}
+
+#[test]
+fn test_basic_2() {
+    let tree = Value::M(vec![
+        ("projects".into(), Value::M(vec![
+            ("385e734a52e13949a7a5c71827f6de920dbfea43".into(), Value::M(vec![
+                ("https://soniex2.autistic.space/git-repos/ganarchy.git".into(), Value::M(vec![
+                    ("HEAD".into(), Value::M(vec![
+                        ("active".into(), Value::B(true)),
+                    ].into_iter().collect())),
+                ].into_iter().collect())),
+            ].into_iter().collect())),
+        ].into_iter().collect())),
+    ].into_iter().collect());
+    let pat = datafu::Pattern::<Value>::compile("->'projects':?$d->P/[0-9a-fA-F]{40}|[0-9a-fA-F]{64}/?:?$d->U:?$d->B", None).ok().unwrap();
+    let mut matcher = pat.attempt_match(&tree);
+    let m = matcher.next();
+    // TODO
+    todo!();
+    //assert m['P'][0] == "385e734a52e13949a7a5c71827f6de920dbfea43"
+    //assert m['U'][0] == "https://soniex2.autistic.space/git-repos/ganarchy.git"
+    //assert m['B'][0] == "HEAD"
+    //assert m['B'][1] == {"active": True}
+}
+
+#[test]
+fn test_spaces() {
+    let tree = Value::M(vec![
+        ("projects".into(), Value::M(vec![
+            ("385e734a52e13949a7a5c71827f6de920dbfea43".into(), Value::M(vec![
+                ("https://soniex2.autistic.space/git-repos/ganarchy.git".into(), Value::M(vec![
+                    ("HEAD".into(), Value::M(vec![
+                        ("active".into(), Value::B(true)),
+                    ].into_iter().collect())),
+                ].into_iter().collect())),
+            ].into_iter().collect())),
+        ].into_iter().collect())),
+    ].into_iter().collect());
+    let pat = datafu::Pattern::<Value>::compile("-> 'projects'?
+                                                    -> commit /[0-9a-fA-F]{40}|[0-9a-fA-F]{64}/? :?$dict
+                                                       -> url :?$dict
+                                                          -> branch :?$dict", None).ok().unwrap();
+    let mut matcher = pat.attempt_match(&tree);
+    let m = matcher.next();
+    // TODO
+    todo!();
+    //assert m['commit'][0] == "385e734a52e13949a7a5c71827f6de920dbfea43"
+    //assert m['url'][0] == "https://soniex2.autistic.space/git-repos/ganarchy.git"
+    //assert m['branch'][0] == "HEAD"
+    //assert m['branch'][1] == {"active": True}
+}
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
new file mode 100644
index 0000000..48153af
--- /dev/null
+++ b/tests/common/mod.rs
@@ -0,0 +1,175 @@
+/*
+ * This file is part of Datafu
+ * Copyright (C) 2021  Soni L.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use std::borrow::Borrow;
+use std::borrow::Cow;
+use std::collections::BTreeMap;
+
+use datafu::RefOwn;
+use datafu::PatternTypes;
+use datafu::KVPair;
+
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
+pub enum Value {
+    U(usize),
+    B(bool),
+    M(BTreeMap<Value, Value>),
+    S(Cow<'static, str>),
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum Dummy {
+}
+
+trait ValueHelper {
+    fn as_value(&self) -> Result<&Value, &str>;
+}
+
+impl ValueHelper for Value {
+    fn as_value(&self) -> Result<&Value, &str> {
+        Ok(self)
+    }
+}
+
+impl ValueHelper for &str {
+    fn as_value(&self) -> Result<&Value, &str> {
+        Err(self)
+    }
+}
+
+impl PartialEq<str> for Value {
+    fn eq(&self, other: &str) -> bool {
+        matches!(self, Value::S(l) if l == other)
+    }
+}
+
+impl PartialEq<Value> for str {
+    fn eq(&self, other: &Value) -> bool {
+        matches!(other, Value::S(r) if self == r)
+    }
+}
+
+impl PartialEq<Dummy> for Value {
+    fn eq(&self, other: &Dummy) -> bool {
+        unreachable!()
+    }
+}
+
+impl PartialEq<Value> for Dummy {
+    fn eq(&self, other: &Value) -> bool {
+        unreachable!()
+    }
+}
+
+impl PartialEq<str> for Dummy {
+    fn eq(&self, other: &str) -> bool {
+        unreachable!()
+    }
+}
+
+impl PartialEq<Dummy> for str {
+    fn eq(&self, other: &Dummy) -> bool {
+        unreachable!()
+    }
+}
+
+impl<'a> PartialEq for dyn ValueHelper + 'a {
+    fn eq(&self, other: &(dyn ValueHelper + 'a)) -> bool {
+        match (self.as_value(), other.as_value()) {
+            (a, b) if a == b => true,
+            (Ok(Value::S(a)), Err(b)) | (Err(b), Ok(Value::S(a))) => {
+                a.eq(b)
+            },
+            _ => false,
+        }
+    }
+}
+
+impl<'a> PartialOrd for dyn ValueHelper + 'a {
+    fn partial_cmp(&self, other: &(dyn ValueHelper + 'a)) -> Option<std::cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl<'a> Eq for dyn ValueHelper + 'a {
+}
+
+impl<'a> Ord for dyn ValueHelper + 'a {
+    fn cmp(&self, other: &(dyn ValueHelper + 'a)) -> std::cmp::Ordering {
+        match (self.as_value(), other.as_value()) {
+            (Ok(a), Ok(b)) => a.cmp(b),
+            (Err(a), Err(b)) => a.cmp(b),
+            (Ok(Value::S(a)), Err(b)) => (**a).cmp(b),
+            (Err(a), Ok(Value::S(b))) => a.cmp(b.borrow()),
+            (Ok(_), Err(_)) => std::cmp::Ordering::Less,
+            (Err(_), Ok(_)) => std::cmp::Ordering::Greater,
+        }
+    }
+}
+
+impl From<&'static str> for Value {
+    fn from(x: &'static str) -> Value {
+        Value::S(x.into())
+    }
+}
+
+
+impl<'a> Borrow<dyn ValueHelper + 'a> for Value {
+    fn borrow(&self) -> &(dyn ValueHelper + 'a) {
+        self
+    }
+}
+
+impl PatternTypes for Value {
+    type Ref = Self;
+    type Own = Dummy;
+
+    fn pairs<'b>(
+        item: RefOwn<'b, Self, Dummy>
+    ) -> Option<Box<dyn Iterator<Item=KVPair<'b, Self>> + 'b>> {
+        match item {
+            RefOwn::Ref(Value::M(map)) => {
+                Some(Box::new(map.iter().map(|(a, b)| (a.into(), b.into()))))
+            },
+            _ => None
+        }
+    }
+
+    fn get<'a, 'b>(
+        item: RefOwn<'b, Self, Dummy>,
+        key: RefOwn<'a, Self, Dummy>
+    ) -> Option<Option<KVPair<'b, Self>>> {
+        match item {
+            RefOwn::Ref(Value::M(map)) => {
+                Some(match key {
+                    RefOwn::Ref(key) => map.get_key_value(key),
+                    RefOwn::Own(key) => unreachable!(),//map.get_key_value(&Value::U(key)),
+                    RefOwn::Str(key) => map.get_key_value(&key as &dyn ValueHelper),
+                }.map(|(k,v)| (k.into(), v.into())))
+            },
+            _ => None
+        }
+    }
+
+    fn matches(
+        left: RefOwn<'_, Self, Dummy>,
+        right: RefOwn<'_, Self, Dummy>
+    ) -> bool {
+        left == right
+    }
+}