forked from rojo-rbx/rojo
Compare commits
4 Commits
v7.7.0-rc.
...
feature/da
| Author | SHA1 | Date | |
|---|---|---|---|
|
c552fdc52e
|
|||
|
|
02b41133f8 | ||
|
|
d08780fc14 | ||
|
|
b89cc7f398 |
@@ -30,6 +30,11 @@ Making a new release? Simply add the new header with the version and date undern
|
||||
-->
|
||||
|
||||
## Unreleased
|
||||
* Fixed a bug caused by having reference properties (such as `ObjectValue.Value`) that point to an Instance not included in syncback. ([#1179])
|
||||
* Fixed instance replacement fallback failing when too many instances needed to be replaced. ([#1192])
|
||||
|
||||
[#1179]: https://github.com/rojo-rbx/rojo/pull/1179
|
||||
[#1192]: https://github.com/rojo-rbx/rojo/pull/1192
|
||||
|
||||
## [7.7.0-rc.1] (November 27th, 2025)
|
||||
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1313,7 +1313,7 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "memofs"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"fs-err",
|
||||
|
||||
@@ -46,7 +46,7 @@ name = "build"
|
||||
harness = false
|
||||
|
||||
[dependencies]
|
||||
memofs = { version = "0.3.0", path = "crates/memofs" }
|
||||
memofs = { version = "0.3.1", path = "crates/memofs" }
|
||||
|
||||
# These dependencies can be uncommented when working on rbx-dom simultaneously
|
||||
# rbx_binary = { path = "../rbx-dom/rbx_binary", features = [
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# memofs Changelog
|
||||
|
||||
## Unreleased Changes
|
||||
|
||||
## 0.3.1 (2025-11-27)
|
||||
* Added `Vfs::exists`. [#1169]
|
||||
* Added `create_dir` and `create_dir_all` to allow creating directories. [#937]
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "memofs"
|
||||
description = "Virtual filesystem with configurable backends."
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
authors = [
|
||||
"Lucien Greathouse <me@lpghatguy.com>",
|
||||
"Micah Reid <git@dekkonot.com>",
|
||||
|
||||
@@ -31,17 +31,11 @@ impl VfsBackend for NoopBackend {
|
||||
}
|
||||
|
||||
fn create_dir(&mut self, _path: &Path) -> io::Result<()> {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"NoopBackend doesn't do anything",
|
||||
))
|
||||
Err(io::Error::other("NoopBackend doesn't do anything"))
|
||||
}
|
||||
|
||||
fn create_dir_all(&mut self, _path: &Path) -> io::Result<()> {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"NoopBackend doesn't do anything",
|
||||
))
|
||||
Err(io::Error::other("NoopBackend doesn't do anything"))
|
||||
}
|
||||
|
||||
fn remove_file(&mut self, _path: &Path) -> io::Result<()> {
|
||||
|
||||
@@ -290,31 +290,39 @@ function ApiContext:open(id)
|
||||
end
|
||||
|
||||
function ApiContext:serialize(ids: { string })
|
||||
local url = ("%s/api/serialize/%s"):format(self.__baseUrl, table.concat(ids, ","))
|
||||
local url = ("%s/api/serialize"):format(self.__baseUrl)
|
||||
local request_body = Http.jsonEncode({ sessionId = self.__sessionId, ids = ids })
|
||||
|
||||
return Http.get(url):andThen(rejectFailedRequests):andThen(Http.Response.json):andThen(function(body)
|
||||
if body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
return Http.post(url, request_body)
|
||||
:andThen(rejectFailedRequests)
|
||||
:andThen(Http.Response.json)
|
||||
:andThen(function(response_body)
|
||||
if response_body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
|
||||
assert(validateApiSerialize(body))
|
||||
assert(validateApiSerialize(response_body))
|
||||
|
||||
return body
|
||||
end)
|
||||
return response_body
|
||||
end)
|
||||
end
|
||||
|
||||
function ApiContext:refPatch(ids: { string })
|
||||
local url = ("%s/api/ref-patch/%s"):format(self.__baseUrl, table.concat(ids, ","))
|
||||
local url = ("%s/api/ref-patch"):format(self.__baseUrl)
|
||||
local request_body = Http.jsonEncode({ sessionId = self.__sessionId, ids = ids })
|
||||
|
||||
return Http.get(url):andThen(rejectFailedRequests):andThen(Http.Response.json):andThen(function(body)
|
||||
if body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
return Http.post(url, request_body)
|
||||
:andThen(rejectFailedRequests)
|
||||
:andThen(Http.Response.json)
|
||||
:andThen(function(response_body)
|
||||
if response_body.sessionId ~= self.__sessionId then
|
||||
return Promise.reject("Server changed ID")
|
||||
end
|
||||
|
||||
assert(validateApiRefPatch(body))
|
||||
assert(validateApiRefPatch(response_body))
|
||||
|
||||
return body
|
||||
end)
|
||||
return response_body
|
||||
end)
|
||||
end
|
||||
|
||||
return ApiContext
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
---
|
||||
Writing src/Pointer1.model.json
|
||||
Writing src/Pointer2.model.json
|
||||
Writing src/Pointer3.model.json
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
source: tests/tests/syncback.rs
|
||||
expression: src/Pointer1.model.json
|
||||
---
|
||||
{
|
||||
"className": "ObjectValue"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
source: tests/tests/syncback.rs
|
||||
expression: src/Pointer2.model.json
|
||||
---
|
||||
{
|
||||
"className": "ObjectValue"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
source: tests/tests/syncback.rs
|
||||
expression: src/Pointer3.model.json
|
||||
---
|
||||
{
|
||||
"className": "ObjectValue"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "ref_properties_pruned",
|
||||
"tree": {
|
||||
"$className": "DataModel",
|
||||
"ServerScriptService": {
|
||||
"$path": "src"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
rojo-test/syncback-tests/ref_properties_pruned/input.rbxl
Normal file
BIN
rojo-test/syncback-tests/ref_properties_pruned/input.rbxl
Normal file
Binary file not shown.
@@ -54,6 +54,11 @@ pub struct SyncbackCommand {
|
||||
/// If provided, the prompt for writing to the file system is skipped.
|
||||
#[clap(long, short = 'y')]
|
||||
pub non_interactive: bool,
|
||||
|
||||
/// If provided, forces syncback to use JSON model files instead of binary
|
||||
/// .rbxm files for instances that would otherwise serialize as binary.
|
||||
#[clap(long)]
|
||||
pub dangerously_force_json: bool,
|
||||
}
|
||||
|
||||
impl SyncbackCommand {
|
||||
@@ -104,6 +109,7 @@ impl SyncbackCommand {
|
||||
&mut dom_old,
|
||||
dom_new,
|
||||
session_old.root_project(),
|
||||
self.dangerously_force_json,
|
||||
)?;
|
||||
log::debug!(
|
||||
"Syncback finished in {:.02}s!",
|
||||
|
||||
@@ -52,6 +52,7 @@ pub fn syncback_loop(
|
||||
old_tree: &mut RojoTree,
|
||||
mut new_tree: WeakDom,
|
||||
project: &Project,
|
||||
force_json: bool,
|
||||
) -> anyhow::Result<FsSnapshot> {
|
||||
let ignore_patterns = project
|
||||
.syncback_rules
|
||||
@@ -153,6 +154,7 @@ pub fn syncback_loop(
|
||||
old_tree,
|
||||
new_tree: &new_tree,
|
||||
project,
|
||||
force_json,
|
||||
};
|
||||
|
||||
let mut snapshots = vec![SyncbackSnapshot {
|
||||
@@ -197,7 +199,7 @@ pub fn syncback_loop(
|
||||
}
|
||||
}
|
||||
|
||||
let middleware = get_best_middleware(&snapshot);
|
||||
let middleware = get_best_middleware(&snapshot, force_json);
|
||||
|
||||
log::trace!(
|
||||
"Middleware for {inst_path} is {:?} (path is {})",
|
||||
@@ -213,10 +215,14 @@ pub fn syncback_loop(
|
||||
let syncback = match middleware.syncback(&snapshot) {
|
||||
Ok(syncback) => syncback,
|
||||
Err(err) if middleware == Middleware::Dir => {
|
||||
let new_middleware = match env::var(DEBUG_MODEL_FORMAT_VAR) {
|
||||
Ok(value) if value == "1" => Middleware::Rbxmx,
|
||||
Ok(value) if value == "2" => Middleware::JsonModel,
|
||||
_ => Middleware::Rbxm,
|
||||
let new_middleware = if force_json {
|
||||
Middleware::JsonModel
|
||||
} else {
|
||||
match env::var(DEBUG_MODEL_FORMAT_VAR) {
|
||||
Ok(value) if value == "1" => Middleware::Rbxmx,
|
||||
Ok(value) if value == "2" => Middleware::JsonModel,
|
||||
_ => Middleware::Rbxm,
|
||||
}
|
||||
};
|
||||
let file_name = snapshot
|
||||
.path
|
||||
@@ -295,7 +301,7 @@ pub struct SyncbackReturn<'sync> {
|
||||
pub removed_children: Vec<InstanceWithMeta<'sync>>,
|
||||
}
|
||||
|
||||
pub fn get_best_middleware(snapshot: &SyncbackSnapshot) -> Middleware {
|
||||
pub fn get_best_middleware(snapshot: &SyncbackSnapshot, force_json: bool) -> Middleware {
|
||||
// At some point, we're better off using an O(1) method for checking
|
||||
// equality for classes like this.
|
||||
static JSON_MODEL_CLASSES: OnceLock<HashSet<&str>> = OnceLock::new();
|
||||
@@ -361,10 +367,18 @@ pub fn get_best_middleware(snapshot: &SyncbackSnapshot) -> Middleware {
|
||||
}
|
||||
|
||||
if middleware == Middleware::Rbxm {
|
||||
middleware = match env::var(DEBUG_MODEL_FORMAT_VAR) {
|
||||
Ok(value) if value == "1" => Middleware::Rbxmx,
|
||||
Ok(value) if value == "2" => Middleware::JsonModel,
|
||||
_ => Middleware::Rbxm,
|
||||
middleware = if force_json {
|
||||
if !inst.children().is_empty() {
|
||||
Middleware::Dir
|
||||
} else {
|
||||
Middleware::JsonModel
|
||||
}
|
||||
} else {
|
||||
match env::var(DEBUG_MODEL_FORMAT_VAR) {
|
||||
Ok(value) if value == "1" => Middleware::Rbxmx,
|
||||
Ok(value) if value == "2" => Middleware::JsonModel,
|
||||
_ => Middleware::Rbxm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@ use rbx_dom_weak::{
|
||||
ustr, Instance, Ustr, WeakDom,
|
||||
};
|
||||
|
||||
use crate::{multimap::MultiMap, REF_ID_ATTRIBUTE_NAME, REF_POINTER_ATTRIBUTE_PREFIX};
|
||||
use crate::{
|
||||
multimap::MultiMap, syncback::snapshot::inst_path, REF_ID_ATTRIBUTE_NAME,
|
||||
REF_POINTER_ATTRIBUTE_PREFIX,
|
||||
};
|
||||
|
||||
pub struct RefLinks {
|
||||
/// A map of referents to each of their Ref properties.
|
||||
@@ -50,6 +53,22 @@ pub fn collect_referents(dom: &WeakDom) -> RefLinks {
|
||||
continue;
|
||||
}
|
||||
|
||||
let target = match dom.get_by_ref(*prop_value) {
|
||||
Some(inst) => inst,
|
||||
None => {
|
||||
// Properties that are Some but point to nothing may as
|
||||
// well be `nil`. Roblox and us never produce these values
|
||||
// but syncback prunes trees without adjusting ref
|
||||
// properties for performance reasons.
|
||||
log::warn!(
|
||||
"Property {}.{} will be `nil` on the disk because the actual value is not being included in syncback",
|
||||
inst_path(dom, inst_ref),
|
||||
prop_name
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
links.insert(
|
||||
inst_ref,
|
||||
RefLink {
|
||||
@@ -58,10 +77,6 @@ pub fn collect_referents(dom: &WeakDom) -> RefLinks {
|
||||
},
|
||||
);
|
||||
|
||||
let target = dom
|
||||
.get_by_ref(*prop_value)
|
||||
.expect("Refs in DOM should point to valid Instances");
|
||||
|
||||
// 1. Check if target has an ID
|
||||
if let Some(id) = get_existing_id(target) {
|
||||
// If it does, we need to check whether that ID is a duplicate
|
||||
|
||||
@@ -20,6 +20,7 @@ pub struct SyncbackData<'sync> {
|
||||
pub(super) old_tree: &'sync RojoTree,
|
||||
pub(super) new_tree: &'sync WeakDom,
|
||||
pub(super) project: &'sync Project,
|
||||
pub(super) force_json: bool,
|
||||
}
|
||||
|
||||
pub struct SyncbackSnapshot<'sync> {
|
||||
@@ -43,7 +44,7 @@ impl<'sync> SyncbackSnapshot<'sync> {
|
||||
path: PathBuf::new(),
|
||||
middleware: None,
|
||||
};
|
||||
let middleware = get_best_middleware(&snapshot);
|
||||
let middleware = get_best_middleware(&snapshot, self.data.force_json);
|
||||
let name = name_for_inst(middleware, snapshot.new_inst(), snapshot.old_inst())?;
|
||||
snapshot.path = self.path.join(name.as_ref());
|
||||
|
||||
@@ -69,7 +70,7 @@ impl<'sync> SyncbackSnapshot<'sync> {
|
||||
path: PathBuf::new(),
|
||||
middleware: None,
|
||||
};
|
||||
let middleware = get_best_middleware(&snapshot);
|
||||
let middleware = get_best_middleware(&snapshot, self.data.force_json);
|
||||
let name = name_for_inst(middleware, snapshot.new_inst(), snapshot.old_inst())?;
|
||||
snapshot.path = base_path.join(name.as_ref());
|
||||
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
//! Defines Rojo's HTTP API, all under /api. These endpoints generally return
|
||||
//! JSON.
|
||||
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
fs,
|
||||
path::PathBuf,
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{collections::HashMap, fs, path::PathBuf, str::FromStr, sync::Arc};
|
||||
|
||||
use futures::{sink::SinkExt, stream::StreamExt};
|
||||
use hyper::{body, Body, Method, Request, Response, StatusCode};
|
||||
@@ -30,7 +24,10 @@ use crate::{
|
||||
},
|
||||
util::{json, json_ok},
|
||||
},
|
||||
web_api::{BufferEncode, InstanceUpdate, RefPatchResponse, SerializeResponse},
|
||||
web_api::{
|
||||
BufferEncode, InstanceUpdate, RefPatchRequest, RefPatchResponse, SerializeRequest,
|
||||
SerializeResponse,
|
||||
},
|
||||
};
|
||||
|
||||
pub async fn call(serve_session: Arc<ServeSession>, mut request: Request<Body>) -> Response<Body> {
|
||||
@@ -53,12 +50,8 @@ pub async fn call(serve_session: Arc<ServeSession>, mut request: Request<Body>)
|
||||
)
|
||||
}
|
||||
}
|
||||
(&Method::GET, path) if path.starts_with("/api/serialize/") => {
|
||||
service.handle_api_serialize(request).await
|
||||
}
|
||||
(&Method::GET, path) if path.starts_with("/api/ref-patch/") => {
|
||||
service.handle_api_ref_patch(request).await
|
||||
}
|
||||
(&Method::POST, "/api/serialize") => service.handle_api_serialize(request).await,
|
||||
(&Method::POST, "/api/ref-patch") => service.handle_api_ref_patch(request).await,
|
||||
|
||||
(&Method::POST, path) if path.starts_with("/api/open/") => {
|
||||
service.handle_api_open(request).await
|
||||
@@ -229,22 +222,30 @@ impl ApiService {
|
||||
/// that correspond to the requested Instances. These values have their
|
||||
/// `Value` property set to point to the requested Instance.
|
||||
async fn handle_api_serialize(&self, request: Request<Body>) -> Response<Body> {
|
||||
let argument = &request.uri().path()["/api/serialize/".len()..];
|
||||
let requested_ids: Result<Vec<Ref>, _> = argument.split(',').map(Ref::from_str).collect();
|
||||
let session_id = self.serve_session.session_id();
|
||||
let body = body::to_bytes(request.into_body()).await.unwrap();
|
||||
|
||||
let requested_ids = match requested_ids {
|
||||
Ok(ids) => ids,
|
||||
Err(_) => {
|
||||
let request: SerializeRequest = match json::from_slice(&body) {
|
||||
Ok(request) => request,
|
||||
Err(err) => {
|
||||
return json(
|
||||
ErrorResponse::bad_request("Malformed ID list"),
|
||||
ErrorResponse::bad_request(format!("Invalid body: {}", err)),
|
||||
StatusCode::BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if request.session_id != session_id {
|
||||
return json(
|
||||
ErrorResponse::bad_request("Wrong session ID"),
|
||||
StatusCode::BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
|
||||
let mut response_dom = WeakDom::new(InstanceBuilder::new("Folder"));
|
||||
|
||||
let tree = self.serve_session.tree();
|
||||
for id in &requested_ids {
|
||||
for id in &request.ids {
|
||||
if let Some(instance) = tree.get_instance(*id) {
|
||||
let clone = response_dom.insert(
|
||||
Ref::none(),
|
||||
@@ -290,20 +291,26 @@ impl ApiService {
|
||||
/// and referent properties need to be updated after the serialize
|
||||
/// endpoint is used.
|
||||
async fn handle_api_ref_patch(self, request: Request<Body>) -> Response<Body> {
|
||||
let argument = &request.uri().path()["/api/ref-patch/".len()..];
|
||||
let requested_ids: Result<HashSet<Ref>, _> =
|
||||
argument.split(',').map(Ref::from_str).collect();
|
||||
let session_id = self.serve_session.session_id();
|
||||
let body = body::to_bytes(request.into_body()).await.unwrap();
|
||||
|
||||
let requested_ids = match requested_ids {
|
||||
Ok(ids) => ids,
|
||||
Err(_) => {
|
||||
let request: RefPatchRequest = match json::from_slice(&body) {
|
||||
Ok(request) => request,
|
||||
Err(err) => {
|
||||
return json(
|
||||
ErrorResponse::bad_request("Malformed ID list"),
|
||||
ErrorResponse::bad_request(format!("Invalid body: {}", err)),
|
||||
StatusCode::BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if request.session_id != session_id {
|
||||
return json(
|
||||
ErrorResponse::bad_request("Wrong session ID"),
|
||||
StatusCode::BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
|
||||
let mut instance_updates: HashMap<Ref, InstanceUpdate> = HashMap::new();
|
||||
|
||||
let tree = self.serve_session.tree();
|
||||
@@ -312,7 +319,7 @@ impl ApiService {
|
||||
let Variant::Ref(prop_value) = prop_value else {
|
||||
continue;
|
||||
};
|
||||
if let Some(target_id) = requested_ids.get(prop_value) {
|
||||
if let Some(target_id) = request.ids.get(prop_value) {
|
||||
let instance_id = instance.id();
|
||||
let update =
|
||||
instance_updates
|
||||
|
||||
@@ -238,6 +238,13 @@ pub struct OpenResponse {
|
||||
pub session_id: SessionId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SerializeRequest {
|
||||
pub session_id: SessionId,
|
||||
pub ids: Vec<Ref>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SerializeResponse {
|
||||
@@ -269,6 +276,13 @@ impl BufferEncode {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RefPatchRequest {
|
||||
pub session_id: SessionId,
|
||||
pub ids: HashSet<Ref>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RefPatchResponse<'a> {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::{
|
||||
fmt::Write as _,
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
@@ -13,8 +12,12 @@ use rbx_dom_weak::types::Ref;
|
||||
|
||||
use tempfile::{tempdir, TempDir};
|
||||
|
||||
use librojo::web_api::{
|
||||
ReadResponse, SerializeResponse, ServerInfoResponse, SocketPacket, SocketPacketType,
|
||||
use librojo::{
|
||||
web_api::{
|
||||
ReadResponse, SerializeRequest, SerializeResponse, ServerInfoResponse, SocketPacket,
|
||||
SocketPacketType,
|
||||
},
|
||||
SessionId,
|
||||
};
|
||||
use rojo_insta_ext::RedactionMap;
|
||||
|
||||
@@ -226,16 +229,19 @@ impl TestServeSession {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_api_serialize(&self, ids: &[Ref]) -> Result<SerializeResponse, reqwest::Error> {
|
||||
let mut id_list = String::with_capacity(ids.len() * 33);
|
||||
for id in ids {
|
||||
write!(id_list, "{id},").unwrap();
|
||||
}
|
||||
id_list.pop();
|
||||
pub fn get_api_serialize(
|
||||
&self,
|
||||
ids: &[Ref],
|
||||
session_id: SessionId,
|
||||
) -> Result<SerializeResponse, reqwest::Error> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let url = format!("http://localhost:{}/api/serialize", self.port);
|
||||
let body = serde_json::to_string(&SerializeRequest {
|
||||
session_id,
|
||||
ids: ids.to_vec(),
|
||||
});
|
||||
|
||||
let url = format!("http://localhost:{}/api/serialize/{}", self.port, id_list);
|
||||
|
||||
reqwest::blocking::get(url)?.json()
|
||||
client.post(url).body((body).unwrap()).send()?.json()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -646,7 +646,7 @@ fn meshpart_with_id() {
|
||||
.unwrap();
|
||||
|
||||
let serialize_response = session
|
||||
.get_api_serialize(&[*meshpart, *objectvalue])
|
||||
.get_api_serialize(&[*meshpart, *objectvalue], info.session_id)
|
||||
.unwrap();
|
||||
|
||||
// We don't assert a snapshot on the SerializeResponse because the model includes the
|
||||
@@ -673,7 +673,9 @@ fn forced_parent() {
|
||||
read_response.intern_and_redact(&mut redactions, root_id)
|
||||
);
|
||||
|
||||
let serialize_response = session.get_api_serialize(&[root_id]).unwrap();
|
||||
let serialize_response = session
|
||||
.get_api_serialize(&[root_id], info.session_id)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(serialize_response.session_id, info.session_id);
|
||||
|
||||
|
||||
@@ -71,8 +71,13 @@ syncback_tests! {
|
||||
ref_properties_conflict => ["src/Pointer_2.model.json", "src/Target_2.model.json"],
|
||||
// Ensures that having multiple pointers that are aimed at the same target doesn't trigger ref rewrites.
|
||||
ref_properties_duplicate => [],
|
||||
// Ensures that ref properties that point to nothing after the prune both
|
||||
// do not leave any trace of themselves
|
||||
ref_properties_pruned => ["src/Pointer1.model.json", "src/Pointer2.model.json", "src/Pointer3.model.json"],
|
||||
// Ensures that the old middleware is respected during syncback
|
||||
respect_old_middleware => ["default.project.json", "src/model_json.model.json", "src/rbxm.rbxm", "src/rbxmx.rbxmx"],
|
||||
// Ensures that the `$schema` field roundtrips with syncback
|
||||
schema_roundtrip => ["default.project.json", "src/model.model.json", "src/init/init.meta.json", "src/adjacent.meta.json"],
|
||||
// Ensures that StringValues inside project files are written to the
|
||||
// project file, but only if they don't have `$path` set
|
||||
string_value_project => ["default.project.json"],
|
||||
@@ -81,5 +86,4 @@ syncback_tests! {
|
||||
sync_rules => ["src/module.modulescript", "src/text.text"],
|
||||
// Ensures that the `syncUnscriptable` setting works
|
||||
unscriptable_properties => ["default.project.json"],
|
||||
schema_roundtrip => ["default.project.json", "src/model.model.json", "src/init/init.meta.json", "src/adjacent.meta.json"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user