Implement tests using tempfile

This commit is contained in:
Lucien Greathouse 2018-04-05 00:08:23 -07:00
parent d9343d09f5
commit 8d4213ddf1
4 changed files with 107 additions and 19 deletions

View file

@ -1,17 +1,22 @@
use std::path::{Path, PathBuf};
use std::collections::HashMap;
use std::io::Read;
use std::io::{Read, Write};
use std::fs::{self, File};
use id::{Id};
// TODO: Add lifetime, switch to using Cow<'a, str> instead of String. It's
// possible that it would be too cumbersome!
#[derive(Debug, Clone)]
struct FileRoute {
partition: String,
route: Vec<String>,
pub partition: String,
pub route: Vec<String>,
}
impl FileRoute {
/// Creates a PathBuf out of the `FileRoute` based on the given partition
/// `Path`.
// TODO: Tests
pub fn to_path_buf(&self, partition_path: &Path) -> PathBuf {
let mut result = partition_path.to_path_buf();
@ -22,6 +27,9 @@ impl FileRoute {
result
}
/// Creates a version of the FileRoute with the given extra pieces appended
/// to the end.
// TODO: Test
pub fn extended_with(&self, pieces: &[&str]) -> FileRoute {
let mut result = self.clone();
@ -33,6 +41,9 @@ impl FileRoute {
}
}
/// Represents a file or directory that has been read from the filesystem.
// TODO: Keep track of file Path or FileRoute?
#[derive(Debug, Clone)]
enum FileItem {
File {
contents: String,
@ -43,32 +54,44 @@ enum FileItem {
}
struct RbxInstance {
parent: Option<Id>,
pub parent: Option<Id>,
}
struct RbxSession {
partitions_path: HashMap<String, PathBuf>,
partition_instances: HashMap<String, Id>,
partition_files: HashMap<String, FileItem>,
pub partition_paths: HashMap<String, PathBuf>,
pub partition_instances: HashMap<String, Id>,
pub partition_files: HashMap<String, FileItem>,
}
impl RbxSession {
fn new() -> RbxSession {
RbxSession {
partition_paths: HashMap::new(),
partition_instances: HashMap::new(),
partition_files: HashMap::new(),
}
}
fn load(&mut self) {
for (partition_name, partition_path) in &self.partitions_path {
let file_item = self.read(&FileRoute {
for (partition_name, partition_path) in &self.partition_paths {
let route = FileRoute {
partition: partition_name.clone(),
route: vec![],
}).expect("aaagh");
};
let file_item = self.read(&route).expect("Couldn't load partitions");
self.partition_files.insert(partition_name.clone(), file_item);
}
}
fn read(&self, route: &FileRoute) -> Result<FileItem, ()> {
let partition_path = self.partitions_path.get(&route.partition)
let partition_path = self.partition_paths.get(&route.partition)
.ok_or(())?;
let path = route.to_path_buf(partition_path);
println!("Read {:?}, path {}", route, path.display());
let metadata = fs::metadata(path)
.map_err(|_| ())?;
@ -82,7 +105,7 @@ impl RbxSession {
}
fn read_file(&self, route: &FileRoute) -> Result<FileItem, ()> {
let partition_path = self.partitions_path.get(&route.partition)
let partition_path = self.partition_paths.get(&route.partition)
.ok_or(())?;
let path = route.to_path_buf(partition_path);
@ -100,7 +123,7 @@ impl RbxSession {
}
fn read_directory(&self, route: &FileRoute) -> Result<FileItem, ()> {
let partition_path = self.partitions_path.get(&route.partition)
let partition_path = self.partition_paths.get(&route.partition)
.ok_or(())?;
let path = route.to_path_buf(partition_path);
@ -118,12 +141,9 @@ impl RbxSession {
let child_route = route.extended_with(&[&name]);
match self.read(&child_route) {
Ok(child_item) => {
children.insert(name, child_item);
},
Err(_) => {},
}
let child_item = self.read(&child_route)?;
children.insert(name, child_item);
}
Ok(FileItem::Directory {
@ -131,3 +151,51 @@ impl RbxSession {
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile;
// I'm not exactly sure how I want to structure these tests
// Essentially, I need a bunch of random files to load, and to measure:
// * What FileItems were loaded?
// * Are changes logged to those FileItems correctly?
// * What RbxInstance objects are generated from them?
// * Are changes propagated from FileItem through to those RbxInstances?
#[test]
fn file_items_correct() {
let root_dir = tempfile::tempdir().unwrap();
let foo_path = root_dir.path().join("foo.txt");
let bar_path = root_dir.path().join("bar.tsv");
{
let mut foo = File::create(foo_path).unwrap();
writeln!(foo, "Hello, foo!").unwrap();
let mut bar = File::create(bar_path).unwrap();
writeln!(bar, "Hello, bar!").unwrap();
}
let mut session = RbxSession::new();
session.partition_paths.insert("agh".to_string(), root_dir.path().to_path_buf());
session.load();
assert_eq!(session.partition_files.len(), 1);
let folder = session.partition_files.values().nth(0).unwrap();
let children = match folder {
&FileItem::Directory { ref children } => children,
_ => panic!("Not a directory!"),
};
assert_eq!(children.len(), 2);
assert!(children.get("foo.txt").is_some());
assert!(children.get("bar.tsv").is_some());
}
}