use std::collections::HashMap;
use anyhow::Result;
use swh_graph::graph::*;
use swh_graph::graph_builder::GraphBuilder;
use swh_graph::labels::{LabelNameId, Permission};
use swh_graph::swhid;
use swh_graph::views::GraphSpy;
use swh_graph_stdlib::*;
use swh_graph_stdlib::fs::IdPath;
mod data;
#[test]
fn test_bitfield_id_path() {
let ids = vec![LabelNameId(5), LabelNameId(3), LabelNameId(7)];
let path = fs::BitFieldIdPath::from(ids.clone());
assert_eq!(path.iter().collect::<Vec<_>>(), ids);
let path = fs::BitFieldIdPath::from(ids.as_slice());
assert_eq!(path.iter().collect::<Vec<_>>(), ids);
let as_box: Box<[LabelNameId]> = path.into();
assert_eq!(&*as_box, ids.as_slice());
let path = fs::BitFieldIdPath::from(&[][..] as &[LabelNameId]);
assert_eq!(path.iter().collect::<Vec<_>>(), vec![]);
}
#[test]
fn test_resolve_path() -> Result<()> {
let graph = data::build_test_fs_tree_1()?;
let props = graph.properties();
let root_node = props.node_id(swhid!(swh:1:dir:0000000000000000000000000000000000000000))?;
assert!(fs::resolve_name(&graph, root_node, "does-not-exist.txt").is_err());
assert_eq!(
props.swhid(fs::resolve_name(&graph, root_node, "README.md")?.unwrap()),
swhid!(swh:1:cnt:0000000000000000000000000000000000000007)
);
assert_eq!(
props.swhid(fs::resolve_name(&graph, root_node, "src")?.unwrap()),
swhid!(swh:1:dir:0000000000000000000000000000000000000001)
);
assert!(fs::resolve_path(&graph, root_node, "does-not-exist.txt").is_err());
assert!(fs::resolve_path(&graph, root_node, "README.md/is-not-a-dir").is_err());
assert_eq!(
props.swhid(fs::resolve_name(&graph, root_node, "doc")?.unwrap()),
swhid!(swh:1:dir:0000000000000000000000000000000000000002)
);
assert_eq!(
props.swhid(fs::resolve_path(&graph, root_node, "src/main.c")?.unwrap()),
swhid!(swh:1:cnt:0000000000000000000000000000000000000004)
);
assert_eq!(
props.swhid(fs::resolve_path(&graph, root_node, "doc/ls/ls.1")?.unwrap()),
swhid!(swh:1:cnt:0000000000000000000000000000000000000006)
);
Ok(())
}
#[test]
fn test_resolve_path_by_id_with_bitfield() -> Result<()> {
let graph = data::build_test_fs_tree_1()?;
let props = graph.properties();
let root_node = props.node_id(swhid!(swh:1:dir:0000000000000000000000000000000000000000))?;
let path = fs::BitFieldIdPath::from(vec![
props.label_name_id(b"src")?,
props.label_name_id(b"main.c")?,
]);
assert_eq!(
props.swhid(fs::resolve_path_by_id(&graph, root_node, path)?.unwrap()),
swhid!(swh:1:cnt:0000000000000000000000000000000000000004)
);
let path = fs::BitFieldIdPath::from(vec![props.label_name_id(b"main.c")?]);
assert_eq!(fs::resolve_path_by_id(&graph, root_node, path)?, None);
Ok(())
}
#[test]
fn test_cached_path_resolver() -> Result<()> {
let mut builder = GraphBuilder::default();
let dir_a = builder
.node(swhid!(swh:1:dir:0000000000000000000000000000000000000010))?
.done();
let dir_b = builder
.node(swhid!(swh:1:dir:0000000000000000000000000000000000000011))?
.done();
let dir_shared = builder
.node(swhid!(swh:1:dir:0000000000000000000000000000000000000012))?
.done();
let dir_inner = builder
.node(swhid!(swh:1:dir:0000000000000000000000000000000000000013))?
.done();
let cnt1 = builder
.node(swhid!(swh:1:cnt:0000000000000000000000000000000000000014))?
.done();
let cnt2 = builder
.node(swhid!(swh:1:cnt:0000000000000000000000000000000000000015))?
.done();
builder.dir_arc(dir_a, dir_shared, Permission::Directory, "src");
builder.dir_arc(dir_b, dir_shared, Permission::Directory, "src");
builder.dir_arc(dir_shared, cnt1, Permission::Content, "README.txt");
builder.dir_arc(dir_shared, dir_inner, Permission::Directory, "src");
builder.dir_arc(dir_inner, cnt2, Permission::Content, "README.txt");
let graph = builder.done()?;
let path = vec![
graph.properties().label_name_id(b"src")?,
graph.properties().label_name_id(b"README.txt")?,
];
let spy = GraphSpy::new(graph);
let history = spy.history.clone();
let walks = || {
history
.lock()
.unwrap()
.drain(..)
.filter(|(m, _)| *m == "untyped_labeled_successors")
.map(|(_, args)| args.clone())
.collect::<Vec<_>>()
};
let mut resolver = fs::CachedPathResolver::new(&spy, path);
assert_eq!(resolver.resolve_from(dir_a)?, Some(cnt1));
assert_eq!(walks(), vec!["(0,)".to_string(), "(2,)".to_string()]);
assert_eq!(resolver.resolve_from(dir_a)?, Some(cnt1));
assert_eq!(walks(), Vec::<String>::new());
assert_eq!(resolver.resolve_from(dir_b)?, Some(cnt1));
assert_eq!(walks(), vec!["(1,)".to_string()]);
assert_eq!(resolver.resolve_from(dir_shared)?, Some(cnt2));
assert_eq!(walks(), vec!["(2,)".to_string(), "(3,)".to_string()]); Ok(())
}
#[test]
fn test_fs_ls_tree() -> Result<()> {
let graph = data::build_test_fs_tree_1()?;
let props = graph.properties();
let doc_dir = props.node_id("swh:1:dir:0000000000000000000000000000000000000002")?;
use swh_graph::labels::Permission;
use swh_graph_stdlib::fs::FsTree::*;
assert_eq!(
fs::ls_tree(&graph, doc_dir)?,
Directory(HashMap::from([(
Vec::from("ls"),
(
Directory(HashMap::from([(
Vec::from("ls.1"),
(Content, Some(Permission::Content))
)])),
Some(Permission::Directory)
)
)]))
);
Ok(())
}