Move some serve code into serve_session.rs, start writing serve session tests

This commit is contained in:
Lucien Greathouse
2019-10-07 16:24:36 -07:00
parent e60be94be0
commit ab6cedb659
3 changed files with 102 additions and 27 deletions

View File

@@ -1,20 +1,16 @@
use std::{
collections::HashMap,
io::{self, Write},
path::PathBuf,
sync::Arc,
};
use failure::Fail;
use rbx_dom_weak::RbxInstanceProperties;
use termcolor::{BufferWriter, Color, ColorChoice, ColorSpec, WriteColor};
use crate::{
imfs::{Imfs, RealFetcher, WatchMode},
project::{Project, ProjectLoadError},
serve_session::ServeSession,
snapshot::{apply_patch_set, compute_patch_set, InstancePropertiesWithMeta, RojoTree},
snapshot_middleware::snapshot_from_imfs,
web::LiveServer,
};
@@ -54,29 +50,14 @@ pub fn serve(options: &ServeOptions) -> Result<(), ServeError> {
let _ = show_start_message(port);
let mut tree = RojoTree::new(InstancePropertiesWithMeta {
properties: RbxInstanceProperties {
name: "ROOT".to_owned(),
class_name: "Folder".to_owned(),
properties: HashMap::new(),
},
metadata: Default::default(),
});
let root_id = tree.get_root_id();
let imfs = Imfs::new(RealFetcher::new(WatchMode::Enabled));
let mut imfs = Imfs::new(RealFetcher::new(WatchMode::Enabled));
let entry = imfs
.get(&options.fuzzy_project_path)
.expect("could not get project path");
let session = Arc::new(ServeSession::new(
imfs,
&options.fuzzy_project_path,
maybe_project,
));
let snapshot = snapshot_from_imfs(&mut imfs, &entry)
.expect("snapshot failed")
.expect("snapshot did not return an instance");
let patch_set = compute_patch_set(&snapshot, &tree, root_id);
apply_patch_set(&mut tree, patch_set);
let session = Arc::new(ServeSession::new(imfs, tree, maybe_project));
let server = LiveServer::new(session);
server.start(port);

View File

@@ -1,16 +1,22 @@
use std::{
collections::HashSet,
path::Path,
sync::{Arc, Mutex, MutexGuard},
time::Instant,
};
use rbx_dom_weak::RbxInstanceProperties;
use crate::{
change_processor::ChangeProcessor,
imfs::{Imfs, ImfsFetcher},
message_queue::MessageQueue,
project::Project,
session_id::SessionId,
snapshot::{AppliedPatchSet, RojoTree},
snapshot::{
apply_patch_set, compute_patch_set, AppliedPatchSet, InstancePropertiesWithMeta, RojoTree,
},
snapshot_middleware::snapshot_from_imfs,
};
/// Contains all of the state for a Rojo serve session.
@@ -70,9 +76,52 @@ pub struct ServeSession<F> {
/// block to prevent needing to spread Send + Sync + 'static into everything
/// that handles ServeSession.
impl<F: ImfsFetcher + Send + 'static> ServeSession<F> {
pub fn new(imfs: Imfs<F>, tree: RojoTree, root_project: Option<Project>) -> Self {
/// Start a new serve session from the given in-memory filesystem and start
/// path.
///
/// The project file is expected to be loaded out-of-band since it's
/// currently loaded from the filesystem directly instead of through the
/// in-memory filesystem layer.
pub fn new<P: AsRef<Path>>(
mut imfs: Imfs<F>,
start_path: P,
root_project: Option<Project>,
) -> Self {
let start_path = start_path.as_ref();
log::trace!(
"Starting new ServeSession at path {} with project {:#?}",
start_path.display(),
root_project
);
let start_time = Instant::now();
log::trace!("Constructing initial tree");
let mut tree = RojoTree::new(InstancePropertiesWithMeta {
properties: RbxInstanceProperties {
name: "ROOT".to_owned(),
class_name: "Folder".to_owned(),
properties: Default::default(),
},
metadata: Default::default(),
});
let root_id = tree.get_root_id();
log::trace!("Loading start path: {}", start_path.display());
let entry = imfs.get(start_path).expect("could not get project path");
log::trace!("Snapshotting start path");
let snapshot = snapshot_from_imfs(&mut imfs, &entry)
.expect("snapshot failed")
.expect("snapshot did not return an instance");
log::trace!("Computing initial patch set");
let patch_set = compute_patch_set(&snapshot, &tree, root_id);
log::trace!("Applying initial patch set");
apply_patch_set(&mut tree, patch_set);
let session_id = SessionId::new();
let message_queue = MessageQueue::new();
@@ -80,6 +129,7 @@ impl<F: ImfsFetcher + Send + 'static> ServeSession<F> {
let message_queue = Arc::new(message_queue);
let imfs = Arc::new(Mutex::new(imfs));
log::trace!("Starting ChangeProcessor");
let change_processor = ChangeProcessor::start(
Arc::clone(&tree),
Arc::clone(&message_queue),
@@ -135,3 +185,32 @@ impl<F: ImfsFetcher> ServeSession<F> {
.and_then(|project| project.serve_place_ids.as_ref())
}
}
/// This module is named to trick Insta into naming the resulting snapshots
/// correctly.
///
/// See https://github.com/mitsuhiko/insta/issues/78
#[cfg(test)]
mod serve_session {
use super::*;
use insta::assert_yaml_snapshot;
use rojo_insta_ext::RedactionMap;
use crate::{
imfs::{ImfsDebug, ImfsSnapshot, NoopFetcher},
tree_view::view_tree,
};
#[test]
fn just_folder() {
let mut imfs = Imfs::new(NoopFetcher);
imfs.debug_load_snapshot("/foo", ImfsSnapshot::empty_dir());
let session = ServeSession::new(imfs, "/foo", None);
let mut rm = RedactionMap::new();
assert_yaml_snapshot!(view_tree(&session.tree(), &mut rm));
}
}

View File

@@ -0,0 +1,15 @@
---
source: src/serve_session.rs
expression: tree_value
---
id: id-1
name: foo
class_name: Folder
properties: {}
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo
relevant_paths:
- /foo
children: []