forked from rojo-rbx/rojo
Improve serve test, add single txt file test
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path};
|
||||||
|
|
||||||
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
||||||
use tempfile::{tempdir, TempDir};
|
use tempfile::{tempdir, TempDir};
|
||||||
|
|||||||
19
rojo-test/serve-test-snapshots/serve_test__just_txt-2.snap
Normal file
19
rojo-test/serve-test-snapshots/serve_test__just_txt-2.snap
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
source: rojo-test/src/serve_test.rs
|
||||||
|
expression: read_result
|
||||||
|
---
|
||||||
|
sessionId: id-1
|
||||||
|
messageCursor: 0
|
||||||
|
instances:
|
||||||
|
id-2:
|
||||||
|
Id: id-2
|
||||||
|
Parent: ~
|
||||||
|
Name: just-txt
|
||||||
|
ClassName: StringValue
|
||||||
|
Properties:
|
||||||
|
Value:
|
||||||
|
Type: String
|
||||||
|
Value: "Hello, world!"
|
||||||
|
Children: []
|
||||||
|
Metadata:
|
||||||
|
ignoreUnknownInstances: false
|
||||||
9
rojo-test/serve-test-snapshots/serve_test__just_txt.snap
Normal file
9
rojo-test/serve-test-snapshots/serve_test__just_txt.snap
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
source: rojo-test/src/serve_test.rs
|
||||||
|
expression: info
|
||||||
|
---
|
||||||
|
sessionId: id-1
|
||||||
|
serverVersion: 0.6.0-dev
|
||||||
|
protocolVersion: 3
|
||||||
|
expectedPlaceIds: ~
|
||||||
|
rootInstanceId: id-2
|
||||||
1
rojo-test/serve-tests/just-txt.txt
Normal file
1
rojo-test/serve-tests/just-txt.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Hello, world!
|
||||||
@@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
mod build_test;
|
mod build_test;
|
||||||
mod serve_test;
|
mod serve_test;
|
||||||
|
mod serve_util;
|
||||||
mod util;
|
mod util;
|
||||||
|
|||||||
@@ -1,24 +1,12 @@
|
|||||||
use std::{
|
use std::fs;
|
||||||
fs,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
process::Command,
|
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
|
||||||
};
|
|
||||||
|
|
||||||
use insta::assert_yaml_snapshot;
|
use insta::assert_yaml_snapshot;
|
||||||
use rbx_dom_weak::RbxId;
|
|
||||||
use tempfile::{tempdir, TempDir};
|
|
||||||
|
|
||||||
use librojo::web_interface::{ReadResponse, ServerInfoResponse};
|
use crate::serve_util::run_serve_test;
|
||||||
use rojo_insta_ext::RedactionMap;
|
|
||||||
|
|
||||||
use crate::util::{
|
|
||||||
copy_recursive, get_rojo_path, get_serve_tests_path, get_working_dir_path, KillOnDrop,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty() {
|
fn empty() {
|
||||||
run_serve_test(|session, mut redactions| {
|
run_serve_test("empty", |session, mut redactions| {
|
||||||
let info = session.get_api_rojo().unwrap();
|
let info = session.get_api_rojo().unwrap();
|
||||||
|
|
||||||
let root_id = info.root_instance_id;
|
let root_id = info.root_instance_id;
|
||||||
@@ -37,112 +25,29 @@ fn empty() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_serve_test(callback: impl FnOnce(TestServeSession, RedactionMap)) {
|
#[test]
|
||||||
let _ = env_logger::try_init();
|
fn just_txt() {
|
||||||
|
run_serve_test("just-txt.txt", |session, mut redactions| {
|
||||||
|
let info = session.get_api_rojo().unwrap();
|
||||||
|
|
||||||
let mut settings = insta::Settings::new();
|
let root_id = info.root_instance_id;
|
||||||
|
let info = redactions.redacted_yaml(info);
|
||||||
|
|
||||||
let snapshot_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("serve-test-snapshots");
|
assert_yaml_snapshot!(info);
|
||||||
settings.set_snapshot_path(snapshot_path);
|
|
||||||
|
|
||||||
let mut redactions = RedactionMap::new();
|
let read_result = session.get_api_read(root_id).unwrap();
|
||||||
|
redactions.intern_iter(read_result.instances.keys().copied());
|
||||||
|
let read_result = redactions.redacted_yaml(read_result);
|
||||||
|
|
||||||
let mut session = TestServeSession::new("empty");
|
assert_yaml_snapshot!(read_result);
|
||||||
let info = session.wait_to_come_online();
|
|
||||||
|
|
||||||
redactions.intern(info.session_id);
|
fs::write(session.path(), "Changed content!").unwrap();
|
||||||
redactions.intern(info.root_instance_id);
|
|
||||||
|
|
||||||
settings.bind(move || callback(session, redactions));
|
// TODO: Directly served files currently don't trigger changed events!
|
||||||
}
|
|
||||||
|
// let subscribe_result = session.get_api_subscribe(0).unwrap();
|
||||||
fn get_port_number() -> usize {
|
// let subscribe_result = redactions.redacted_yaml(subscribe_result);
|
||||||
static NEXT_PORT_NUMBER: AtomicUsize = AtomicUsize::new(35103);
|
|
||||||
|
// assert_yaml_snapshot!(subscribe_result);
|
||||||
NEXT_PORT_NUMBER.fetch_add(1, Ordering::SeqCst)
|
});
|
||||||
}
|
|
||||||
|
|
||||||
struct TestServeSession {
|
|
||||||
// Drop order is important here: we want the process to be killed before the
|
|
||||||
// directory it's operating on is destroyed.
|
|
||||||
rojo_process: KillOnDrop,
|
|
||||||
_dir: TempDir,
|
|
||||||
|
|
||||||
port: usize,
|
|
||||||
project_path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TestServeSession {
|
|
||||||
pub fn new(name: &str) -> Self {
|
|
||||||
let serve_test_path = get_serve_tests_path();
|
|
||||||
let working_dir = get_working_dir_path();
|
|
||||||
let exe_path = get_rojo_path();
|
|
||||||
|
|
||||||
let source_path = serve_test_path.join(name);
|
|
||||||
let dir = tempdir().expect("Couldn't create temporary directory");
|
|
||||||
let project_path = dir.path().join(name);
|
|
||||||
|
|
||||||
fs::create_dir(&project_path).expect("Couldn't create temporary project subdirectory");
|
|
||||||
|
|
||||||
copy_recursive(&source_path, &project_path)
|
|
||||||
.expect("Couldn't copy project to temporary directory");
|
|
||||||
|
|
||||||
let port = get_port_number();
|
|
||||||
let port_string = port.to_string();
|
|
||||||
|
|
||||||
let rojo_process = Command::new(exe_path)
|
|
||||||
.args(&[
|
|
||||||
"serve",
|
|
||||||
project_path.to_str().unwrap(),
|
|
||||||
"--port",
|
|
||||||
port_string.as_str(),
|
|
||||||
])
|
|
||||||
.current_dir(working_dir)
|
|
||||||
.spawn()
|
|
||||||
.expect("Couldn't start Rojo");
|
|
||||||
|
|
||||||
TestServeSession {
|
|
||||||
rojo_process: KillOnDrop(rojo_process),
|
|
||||||
_dir: dir,
|
|
||||||
port,
|
|
||||||
project_path,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn wait_to_come_online(&mut self) -> ServerInfoResponse {
|
|
||||||
loop {
|
|
||||||
match self.rojo_process.0.try_wait() {
|
|
||||||
Ok(Some(status)) => panic!("Rojo process exited with status {}", status),
|
|
||||||
Ok(None) => { /* process is still running */ }
|
|
||||||
Err(err) => panic!("Failed to wait on Rojo process: {}", err),
|
|
||||||
}
|
|
||||||
|
|
||||||
let info = match self.get_api_rojo() {
|
|
||||||
Ok(info) => info,
|
|
||||||
Err(err) => {
|
|
||||||
log::debug!("Server error, retrying: {}", err);
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(30));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
log::info!("Got session info: {:?}", info);
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_api_rojo(&self) -> Result<ServerInfoResponse, reqwest::Error> {
|
|
||||||
let url = format!("http://localhost:{}/api/rojo", self.port);
|
|
||||||
let body = reqwest::get(&url)?.text()?;
|
|
||||||
|
|
||||||
Ok(serde_json::from_str(&body).expect("Server returned malformed response"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_api_read(&self, id: RbxId) -> Result<ReadResponse, reqwest::Error> {
|
|
||||||
let url = format!("http://localhost:{}/api/read/{}", self.port, id);
|
|
||||||
let body = reqwest::get(&url)?.text()?;
|
|
||||||
|
|
||||||
Ok(serde_json::from_str(&body).expect("Server returned malformed response"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
145
rojo-test/src/serve_util.rs
Normal file
145
rojo-test/src/serve_util.rs
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
process::Command,
|
||||||
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
|
use rbx_dom_weak::RbxId;
|
||||||
|
use tempfile::{tempdir, TempDir};
|
||||||
|
|
||||||
|
use librojo::web_interface::{ReadResponse, ServerInfoResponse, SubscribeResponse};
|
||||||
|
use rojo_insta_ext::RedactionMap;
|
||||||
|
|
||||||
|
use crate::util::{
|
||||||
|
copy_recursive, get_rojo_path, get_serve_tests_path, get_working_dir_path, KillOnDrop,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn run_serve_test(test_name: &str, callback: impl FnOnce(TestServeSession, RedactionMap)) {
|
||||||
|
let _ = env_logger::try_init();
|
||||||
|
|
||||||
|
let mut settings = insta::Settings::new();
|
||||||
|
|
||||||
|
let snapshot_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("serve-test-snapshots");
|
||||||
|
settings.set_snapshot_path(snapshot_path);
|
||||||
|
|
||||||
|
let mut redactions = RedactionMap::new();
|
||||||
|
|
||||||
|
let mut session = TestServeSession::new(test_name);
|
||||||
|
let info = session.wait_to_come_online();
|
||||||
|
|
||||||
|
redactions.intern(info.session_id);
|
||||||
|
redactions.intern(info.root_instance_id);
|
||||||
|
|
||||||
|
settings.bind(move || callback(session, redactions));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_port_number() -> usize {
|
||||||
|
static NEXT_PORT_NUMBER: AtomicUsize = AtomicUsize::new(35103);
|
||||||
|
|
||||||
|
NEXT_PORT_NUMBER.fetch_add(1, Ordering::SeqCst)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TestServeSession {
|
||||||
|
// Drop order is important here: we want the process to be killed before the
|
||||||
|
// directory it's operating on is destroyed.
|
||||||
|
rojo_process: KillOnDrop,
|
||||||
|
_dir: TempDir,
|
||||||
|
|
||||||
|
port: usize,
|
||||||
|
project_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestServeSession {
|
||||||
|
pub fn new(name: &str) -> Self {
|
||||||
|
let serve_test_path = get_serve_tests_path();
|
||||||
|
let working_dir = get_working_dir_path();
|
||||||
|
let exe_path = get_rojo_path();
|
||||||
|
|
||||||
|
let source_path = serve_test_path.join(name);
|
||||||
|
let dir = tempdir().expect("Couldn't create temporary directory");
|
||||||
|
let project_path = dir.path().join(name);
|
||||||
|
|
||||||
|
let source_is_file = fs::metadata(&source_path).unwrap().is_file();
|
||||||
|
|
||||||
|
if source_is_file {
|
||||||
|
fs::copy(&source_path, &project_path).expect("couldn't copy project file");
|
||||||
|
} else {
|
||||||
|
fs::create_dir(&project_path).expect("Couldn't create temporary project subdirectory");
|
||||||
|
|
||||||
|
copy_recursive(&source_path, &project_path)
|
||||||
|
.expect("Couldn't copy project to temporary directory");
|
||||||
|
};
|
||||||
|
|
||||||
|
let port = get_port_number();
|
||||||
|
let port_string = port.to_string();
|
||||||
|
|
||||||
|
let rojo_process = Command::new(exe_path)
|
||||||
|
.args(&[
|
||||||
|
"serve",
|
||||||
|
project_path.to_str().unwrap(),
|
||||||
|
"--port",
|
||||||
|
port_string.as_str(),
|
||||||
|
])
|
||||||
|
.current_dir(working_dir)
|
||||||
|
.spawn()
|
||||||
|
.expect("Couldn't start Rojo");
|
||||||
|
|
||||||
|
TestServeSession {
|
||||||
|
rojo_process: KillOnDrop(rojo_process),
|
||||||
|
_dir: dir,
|
||||||
|
port,
|
||||||
|
project_path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &Path {
|
||||||
|
&self.project_path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wait_to_come_online(&mut self) -> ServerInfoResponse {
|
||||||
|
loop {
|
||||||
|
match self.rojo_process.0.try_wait() {
|
||||||
|
Ok(Some(status)) => panic!("Rojo process exited with status {}", status),
|
||||||
|
Ok(None) => { /* process is still running */ }
|
||||||
|
Err(err) => panic!("Failed to wait on Rojo process: {}", err),
|
||||||
|
}
|
||||||
|
|
||||||
|
let info = match self.get_api_rojo() {
|
||||||
|
Ok(info) => info,
|
||||||
|
Err(err) => {
|
||||||
|
log::debug!("Server error, retrying: {}", err);
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(30));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
log::info!("Got session info: {:?}", info);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_api_rojo(&self) -> Result<ServerInfoResponse, reqwest::Error> {
|
||||||
|
let url = format!("http://localhost:{}/api/rojo", self.port);
|
||||||
|
let body = reqwest::get(&url)?.text()?;
|
||||||
|
|
||||||
|
Ok(serde_json::from_str(&body).expect("Server returned malformed response"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_api_read(&self, id: RbxId) -> Result<ReadResponse, reqwest::Error> {
|
||||||
|
let url = format!("http://localhost:{}/api/read/{}", self.port, id);
|
||||||
|
let body = reqwest::get(&url)?.text()?;
|
||||||
|
|
||||||
|
Ok(serde_json::from_str(&body).expect("Server returned malformed response"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_api_subscribe(
|
||||||
|
&self,
|
||||||
|
cursor: u32,
|
||||||
|
) -> Result<SubscribeResponse<'static>, reqwest::Error> {
|
||||||
|
let url = format!("http://localhost:{}/api/subscribe/{}", self.port, cursor);
|
||||||
|
|
||||||
|
reqwest::get(&url)?.json()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user