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

14
server/Cargo.lock generated
View file

@ -608,6 +608,7 @@ dependencies = [
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -725,6 +726,18 @@ dependencies = [
"remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempfile"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "term"
version = "0.2.14"
@ -1021,6 +1034,7 @@ dependencies = [
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "439d9a7c00f98b1b5ee730039bf5b1f9203d508690e3c76b509e7ad59f8f7c99"
"checksum term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "f2077e54d38055cf1ca0fd7933a2e00cd3ec8f6fed352b2a377f06dcdaaf3281"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"

View file

@ -24,3 +24,6 @@ notify = "4.0.0"
rand = "0.3"
regex = "0.2"
lazy_static = "1.0"
[dev-dependencies]
tempfile = "3"

View file

@ -7,6 +7,9 @@ extern crate serde;
extern crate serde_json;
extern crate regex;
#[cfg(test)]
extern crate tempfile;
pub mod rbx_session;
pub mod id;
pub mod web;

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());
}
}