mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-23 14:15:24 +00:00
Break redaction stuff out into separate crate
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -1474,6 +1474,7 @@ dependencies = [
|
|||||||
"regex 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ritz 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ritz 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rojo-insta-ext 0.1.0",
|
||||||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1483,6 +1484,15 @@ dependencies = [
|
|||||||
"winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rojo-insta-ext"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"insta 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rojo-test"
|
name = "rojo-test"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -1494,9 +1504,9 @@ dependencies = [
|
|||||||
"rbx_dom_weak 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rbx_dom_weak 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rojo 0.6.0-dev",
|
"rojo 0.6.0-dev",
|
||||||
|
"rojo-insta-ext 0.1.0",
|
||||||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -21,11 +21,13 @@ dev-live-assets = []
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"rojo-test",
|
"rojo-test",
|
||||||
|
"rojo-insta-ext",
|
||||||
]
|
]
|
||||||
|
|
||||||
default-members = [
|
default-members = [
|
||||||
".",
|
".",
|
||||||
"rojo-test",
|
"rojo-test",
|
||||||
|
"rojo-insta-ext",
|
||||||
]
|
]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
@@ -65,6 +67,7 @@ uuid = { version = "0.7", features = ["v4", "serde"] }
|
|||||||
winreg = "0.6.2"
|
winreg = "0.6.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
rojo-insta-ext = { path = "rojo-insta-ext" }
|
||||||
lazy_static = "1.2"
|
lazy_static = "1.2"
|
||||||
paste = "0.1"
|
paste = "0.1"
|
||||||
pretty_assertions = "0.6.1"
|
pretty_assertions = "0.6.1"
|
||||||
|
|||||||
14
rojo-insta-ext/Cargo.toml
Normal file
14
rojo-insta-ext/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "rojo-insta-ext"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = "1.0.99"
|
||||||
|
serde_yaml = "0.8.9"
|
||||||
|
|
||||||
|
[dependencies.insta]
|
||||||
|
version = "0.11.0"
|
||||||
|
features = ["redactions"]
|
||||||
2
rojo-insta-ext/README.md
Normal file
2
rojo-insta-ext/README.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Rojo Insta Extensions
|
||||||
|
This crate has add-ons intended for use with Insta that are useful for snapshot tests.
|
||||||
3
rojo-insta-ext/src/lib.rs
Normal file
3
rojo-insta-ext/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mod redaction_map;
|
||||||
|
|
||||||
|
pub use redaction_map::*;
|
||||||
75
rojo-insta-ext/src/redaction_map.rs
Normal file
75
rojo-insta-ext/src/redaction_map.rs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
/// Enables redacting any value that serializes as a string.
|
||||||
|
///
|
||||||
|
/// Used for transforming Rojo instance IDs into something deterministic.
|
||||||
|
pub struct RedactionMap {
|
||||||
|
ids: HashMap<String, usize>,
|
||||||
|
last_id: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RedactionMap {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
ids: HashMap::new(),
|
||||||
|
last_id: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn intern(&mut self, id: impl ToString) {
|
||||||
|
let last_id = &mut self.last_id;
|
||||||
|
|
||||||
|
self.ids.entry(id.to_string()).or_insert_with(|| {
|
||||||
|
*last_id += 1;
|
||||||
|
*last_id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn intern_iter<S: ToString>(&mut self, ids: impl Iterator<Item = S>) {
|
||||||
|
for id in ids {
|
||||||
|
self.intern(id.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redacted_yaml(&self, value: impl Serialize) -> serde_yaml::Value {
|
||||||
|
let mut encoded = serde_yaml::to_value(value).expect("Couldn't encode value as YAML");
|
||||||
|
|
||||||
|
self.redact(&mut encoded);
|
||||||
|
encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redact(&self, yaml_value: &mut serde_yaml::Value) {
|
||||||
|
use serde_yaml::{Mapping, Value};
|
||||||
|
|
||||||
|
match yaml_value {
|
||||||
|
Value::String(value) => {
|
||||||
|
if let Some(redacted) = self.ids.get(value) {
|
||||||
|
*yaml_value = Value::String(format!("id-{}", *redacted));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Sequence(sequence) => {
|
||||||
|
for value in sequence {
|
||||||
|
self.redact(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Mapping(mapping) => {
|
||||||
|
// We can't mutate the keys of a map in-place, so we take
|
||||||
|
// ownership of the map and rebuild it.
|
||||||
|
|
||||||
|
let owned_map = std::mem::replace(mapping, Mapping::new());
|
||||||
|
let mut new_map = Mapping::with_capacity(owned_map.len());
|
||||||
|
|
||||||
|
for (mut key, mut value) in owned_map {
|
||||||
|
self.redact(&mut key);
|
||||||
|
self.redact(&mut value);
|
||||||
|
new_map.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
*mapping = new_map;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,9 +13,9 @@ rbx_dom_weak = "1.9.0"
|
|||||||
reqwest = "0.9.20"
|
reqwest = "0.9.20"
|
||||||
serde = "1.0.99"
|
serde = "1.0.99"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
serde_yaml = "0.8.9"
|
|
||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
walkdir = "2.2.9"
|
walkdir = "2.2.9"
|
||||||
|
rojo-insta-ext = { path = "../rojo-insta-ext" }
|
||||||
|
|
||||||
# We execute Rojo via std::process::Command, so depend on it so it's built!
|
# We execute Rojo via std::process::Command, so depend on it so it's built!
|
||||||
rojo = { path = ".." }
|
rojo = { path = ".." }
|
||||||
|
|||||||
8
rojo-test/README.md
Normal file
8
rojo-test/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# rojo-test
|
||||||
|
This project does end-to-end testing of Rojo by executing it and checking what side-effects it has.
|
||||||
|
|
||||||
|
rojo-test is meant to be run as a test with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo test
|
||||||
|
```
|
||||||
@@ -11,6 +11,7 @@ use rbx_dom_weak::RbxId;
|
|||||||
use tempfile::{tempdir, TempDir};
|
use tempfile::{tempdir, TempDir};
|
||||||
|
|
||||||
use librojo::web_interface::{ReadResponse, ServerInfoResponse};
|
use librojo::web_interface::{ReadResponse, ServerInfoResponse};
|
||||||
|
use rojo_insta_ext::RedactionMap;
|
||||||
|
|
||||||
use crate::util::{
|
use crate::util::{
|
||||||
copy_recursive, get_rojo_path, get_serve_tests_path, get_working_dir_path, KillOnDrop,
|
copy_recursive, get_rojo_path, get_serve_tests_path, get_working_dir_path, KillOnDrop,
|
||||||
@@ -18,28 +19,26 @@ use crate::util::{
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty() {
|
fn empty() {
|
||||||
run_serve_test(|session, mut dm| {
|
run_serve_test(|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;
|
||||||
|
|
||||||
let mut info = serde_yaml::to_value(info).unwrap();
|
let info = redactions.redacted_yaml(info);
|
||||||
dm.redact(&mut info);
|
|
||||||
|
|
||||||
assert_yaml_snapshot!(info);
|
assert_yaml_snapshot!(info);
|
||||||
|
|
||||||
let read_result = session.get_api_read(root_id).unwrap();
|
let read_result = session.get_api_read(root_id).unwrap();
|
||||||
|
|
||||||
dm.intern_iter(read_result.instances.keys().copied());
|
redactions.intern_iter(read_result.instances.keys().copied());
|
||||||
|
|
||||||
let mut read_result = serde_yaml::to_value(read_result).unwrap();
|
let read_result = redactions.redacted_yaml(read_result);
|
||||||
dm.redact(&mut read_result);
|
|
||||||
|
|
||||||
assert_yaml_snapshot!(read_result);
|
assert_yaml_snapshot!(read_result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_serve_test(callback: impl FnOnce(TestServeSession, DeterMap)) {
|
fn run_serve_test(callback: impl FnOnce(TestServeSession, RedactionMap)) {
|
||||||
let _ = env_logger::try_init();
|
let _ = env_logger::try_init();
|
||||||
|
|
||||||
let mut settings = insta::Settings::new();
|
let mut settings = insta::Settings::new();
|
||||||
@@ -47,77 +46,15 @@ fn run_serve_test(callback: impl FnOnce(TestServeSession, DeterMap)) {
|
|||||||
let snapshot_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("serve-test-snapshots");
|
let snapshot_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("serve-test-snapshots");
|
||||||
settings.set_snapshot_path(snapshot_path);
|
settings.set_snapshot_path(snapshot_path);
|
||||||
|
|
||||||
let mut dm = DeterMap::new();
|
let mut redactions = RedactionMap::new();
|
||||||
|
|
||||||
let mut session = TestServeSession::new("empty");
|
let mut session = TestServeSession::new("empty");
|
||||||
let info = session.wait_to_come_online();
|
let info = session.wait_to_come_online();
|
||||||
|
|
||||||
dm.intern(info.session_id);
|
redactions.intern(info.session_id);
|
||||||
dm.intern(info.root_instance_id);
|
redactions.intern(info.root_instance_id);
|
||||||
|
|
||||||
settings.bind(move || callback(session, dm));
|
settings.bind(move || callback(session, redactions));
|
||||||
}
|
|
||||||
|
|
||||||
struct DeterMap {
|
|
||||||
ids: HashMap<String, usize>,
|
|
||||||
last_id: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeterMap {
|
|
||||||
fn new() -> DeterMap {
|
|
||||||
DeterMap {
|
|
||||||
ids: HashMap::new(),
|
|
||||||
last_id: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn intern(&mut self, id: impl ToString) {
|
|
||||||
let last_id = &mut self.last_id;
|
|
||||||
|
|
||||||
self.ids.entry(id.to_string()).or_insert_with(|| {
|
|
||||||
*last_id += 1;
|
|
||||||
*last_id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn intern_iter<S: ToString>(&mut self, ids: impl Iterator<Item = S>) {
|
|
||||||
for id in ids {
|
|
||||||
self.intern(id.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn redact(&self, yaml_value: &mut serde_yaml::Value) {
|
|
||||||
use serde_yaml::{Mapping, Value};
|
|
||||||
|
|
||||||
match yaml_value {
|
|
||||||
Value::String(value) => {
|
|
||||||
if let Some(redacted) = self.ids.get(value) {
|
|
||||||
*yaml_value = Value::String(format!("id-{}", *redacted));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Value::Sequence(sequence) => {
|
|
||||||
for value in sequence {
|
|
||||||
self.redact(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Value::Mapping(mapping) => {
|
|
||||||
// We can't mutate the keys of a map in-place, so we take
|
|
||||||
// ownership of the map and rebuild it.
|
|
||||||
|
|
||||||
let owned_map = std::mem::replace(mapping, Mapping::new());
|
|
||||||
let mut new_map = Mapping::with_capacity(owned_map.len());
|
|
||||||
|
|
||||||
for (mut key, mut value) in owned_map {
|
|
||||||
self.redact(&mut key);
|
|
||||||
self.redact(&mut value);
|
|
||||||
new_map.insert(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
*mapping = new_map;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_port_number() -> usize {
|
fn get_port_number() -> usize {
|
||||||
|
|||||||
Reference in New Issue
Block a user