/* * 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 . */ extern crate datafu; mod common; use common::Value; use datafu::RefOwn; #[test] fn test_basic() { 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 preds = vec![("dict", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>)].into_iter().collect(); let pat = datafu::Pattern::::compile::<&str, &str>("->X:?$dict->Y", Some(preds), None).unwrap(); let mut matcher = pat.attempt_match(&tree); let m = matcher.next().unwrap().unwrap(); assert_eq!(m["X"].0, RefOwn::Ref(&Value::from("bar"))); assert_eq!(m["Y"].0, RefOwn::Ref(&Value::from("baz"))); assert_eq!(m["Y"].1, RefOwn::Ref(&Value::U(2))); assert!(matcher.next().is_none()); } #[test] fn test_str() { 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 preds = vec![("dict", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>)].into_iter().collect(); let pat = datafu::Pattern::::compile::<&str, &str>("->X'bar'->Y", Some(preds), None).unwrap(); let mut matcher = pat.attempt_match(&tree); let m = matcher.next().unwrap().unwrap(); assert_eq!(m["X"].0, RefOwn::Ref(&Value::from("bar"))); assert_eq!(m["Y"].0, RefOwn::Ref(&Value::from("baz"))); assert_eq!(m["Y"].1, RefOwn::Ref(&Value::U(2))); assert!(matcher.next().is_none()); } #[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 preds = vec![("d", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>)].into_iter().collect(); let pat = datafu::Pattern::::compile::<&str, &str>("->'projects':?$d->P/[0-9a-fA-F]{40}|[0-9a-fA-F]{64}/?:?$d->U:?$d->B", Some(preds), None).unwrap(); let mut matcher = pat.attempt_match(&tree); let m = matcher.next().unwrap().unwrap(); assert_eq!(m["P"].0, RefOwn::Ref(&Value::from("385e734a52e13949a7a5c71827f6de920dbfea43"))); assert_eq!(m["U"].0, RefOwn::Ref(&Value::from("https://soniex2.autistic.space/git-repos/ganarchy.git"))); assert_eq!(m["B"].0, RefOwn::Ref(&Value::from("HEAD"))); assert_eq!(m["B"].1, RefOwn::Ref(&Value::M(vec![(Value::from("active"), Value::B(true))].into_iter().collect()))); assert!(matcher.next().is_none()); } #[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 preds = vec![("dict", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>)].into_iter().collect(); let pat = datafu::Pattern::::compile::<_, &str>(" -> 'projects'? -> commit /[0-9a-fA-F]{40}|[0-9a-fA-F]{64}/? :?$dict -> url :?$dict -> branch :?$dict", Some(preds), None, ).unwrap(); let mut matcher = pat.attempt_match(&tree); let m = matcher.next().unwrap().unwrap(); assert_eq!(m["commit"].0, RefOwn::Ref(&Value::from("385e734a52e13949a7a5c71827f6de920dbfea43"))); assert_eq!(m["url"].0, RefOwn::Ref(&Value::from("https://soniex2.autistic.space/git-repos/ganarchy.git"))); assert_eq!(m["branch"].0, RefOwn::Ref(&Value::from("HEAD"))); assert_eq!(m["branch"].1, RefOwn::Ref(&Value::M(vec![(Value::from("active"), Value::B(true))].into_iter().collect()))); assert!(matcher.next().is_none()); } #[test] fn test_harder() { 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 preds = vec![ ("dict", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::M(_)))) as Box>), ("str", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::S(_)))) as Box>), ("bool", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::B(_)))) as Box>), // stubs, we don't particularly need to test these ("commit", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::S(_)))) as Box>), ("uri", Box::new(|v: RefOwn<'_, _, _>| matches!(v, RefOwn::Ref(&Value::S(_)))) as Box>), ].into_iter().collect(); let pat = datafu::Pattern::::compile::<_, &str>(" ->'projects':$dict ->commit[:?$str:?$commit]:?$dict ->url[:?$str:?$uri]:?$dict ->branch:?$dict (->active'active'?:?$bool) (->federate'federate'?:?$bool)?", Some(preds), None, ).unwrap(); let mut matcher = pat.attempt_match(&tree); let m = matcher.next().unwrap().unwrap(); assert_eq!(m["commit"].0, RefOwn::Ref(&Value::from("385e734a52e13949a7a5c71827f6de920dbfea43"))); assert_eq!(m["url"].0, RefOwn::Ref(&Value::from("https://soniex2.autistic.space/git-repos/ganarchy.git"))); assert_eq!(m["branch"].0, RefOwn::Ref(&Value::from("HEAD"))); assert_eq!(m["active"].1, RefOwn::Ref(&Value::B(true))); assert_eq!(m.get("federate"), None); assert!(matcher.next().is_none()); }