Translate asset and archive parity tests
This commit is contained in:
828
tests/compat/tests/asset_capability_semantics.rs
Normal file
828
tests/compat/tests/asset_capability_semantics.rs
Normal file
@@ -0,0 +1,828 @@
|
||||
#![allow(
|
||||
clippy::float_cmp,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::too_many_lines
|
||||
)]
|
||||
|
||||
// Exact BSD-3-Clause fixture provenance at LibreMetaverse
|
||||
// 2aa70bb68513b39795da5d13c88f31b86e85a3ba (see LICENSE.md):
|
||||
// GLTFMaterialOverrideCapTests.cs 4d717ded7cc7bd4e68210417f722a1ceec6391b19dc3b1dfeb558ae16e6f115b
|
||||
// GLTFMaterialUploadTests.cs 0602d1504e405868d7bcb608eb7c0db9f47e9ec6636846f34d48669aa5a27025
|
||||
// TerrainMaterialOverrideTests.cs b9409ba65906e2b9d30d42b350b4b3e9c1655d4a503c4ff87bd548dd229dad88
|
||||
// SendPostcardTests.cs 56691373dfa8f817f0b1079b8ec40f16e0186d6cfb13f772da0ffe3935188b4d
|
||||
// UploadThumbnailTests.cs 8a88c5e4d45e7e1d4f8a41092528eefee347c7bd5f5e6f3af171ac19455e894b
|
||||
// ConstructorNullArgumentTests.cs 28deea0bf4d9353a2424842c6184abab8fe82746ceb12e093912728a247f21bc
|
||||
|
||||
use libremetaverse::assets::AssetMaterial;
|
||||
use libremetaverse::{
|
||||
AssetManager, GLTFMaterialUpdate, GridClient, HttpCapsClient, InventoryFolder, Simulator,
|
||||
};
|
||||
use libremetaverse_compat_tests::block_on;
|
||||
use libremetaverse_types::compat::{HttpMessageHandler, HttpRequest, HttpResponse, Uri};
|
||||
use libremetaverse_types::{Color4, Error, UUID, Vector3};
|
||||
use std::collections::{BTreeMap, HashMap, VecDeque};
|
||||
use std::fmt::Write as _;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
const MODIFY_MATERIAL: &str = "http://test.invalid/modify-material-params";
|
||||
const MATERIAL_AGENT: &str = "http://test.invalid/update-material-agent-inventory";
|
||||
const MATERIAL_TASK: &str = "http://test.invalid/update-material-task-inventory";
|
||||
const MATERIAL_UPLOADER: &str = "http://test.invalid/update-material/upload/abc123";
|
||||
const MODIFY_REGION: &str = "http://test.invalid/modify-region";
|
||||
const POSTCARD: &str = "http://test.invalid/send-postcard";
|
||||
const POSTCARD_UPLOADER: &str = "http://test.invalid/send-postcard/upload/abc123";
|
||||
const THUMBNAIL: &str = "http://test.invalid/inventory-thumbnail-upload";
|
||||
const THUMBNAIL_UPLOADER: &str = "http://test.invalid/inventory-thumbnail-upload/upload/abc123";
|
||||
const SEED_CAPS: &str = "http://test.invalid/seed";
|
||||
const OTHER_CAP: &str = "http://test.invalid/other";
|
||||
|
||||
#[derive(Clone)]
|
||||
struct RecordingHttp {
|
||||
requests: Arc<Mutex<Vec<HttpRequest>>>,
|
||||
}
|
||||
|
||||
impl RecordingHttp {
|
||||
fn new(
|
||||
capabilities: &[(&str, &str)],
|
||||
responses: &[(&str, &str)],
|
||||
) -> (Self, HttpMessageHandler) {
|
||||
let requests = Arc::new(Mutex::new(Vec::new()));
|
||||
let recorded = Arc::clone(&requests);
|
||||
let mut queued = HashMap::<String, VecDeque<HttpResponse>>::new();
|
||||
for (uri, body) in responses {
|
||||
queued
|
||||
.entry((*uri).into())
|
||||
.or_default()
|
||||
.push_back(response(body));
|
||||
}
|
||||
let queued = Mutex::new(queued);
|
||||
let mut seed_body = "<llsd><map>".to_owned();
|
||||
for (name, uri) in capabilities {
|
||||
write!(seed_body, "<key>{name}</key><uri>{uri}</uri>")
|
||||
.expect("writing to a String cannot fail");
|
||||
}
|
||||
seed_body.push_str("</map></llsd>");
|
||||
let handler = HttpMessageHandler::new(move |request, _| {
|
||||
let uri = request.uri.0.clone();
|
||||
let response = if uri == SEED_CAPS {
|
||||
HttpResponse {
|
||||
status_code: 200,
|
||||
headers: BTreeMap::new(),
|
||||
content_type: Some("application/llsd+xml".into()),
|
||||
body: seed_body.as_bytes().to_vec(),
|
||||
}
|
||||
} else {
|
||||
recorded.lock().expect("request recording").push(request);
|
||||
queued
|
||||
.lock()
|
||||
.expect("response queue")
|
||||
.get_mut(&uri)
|
||||
.and_then(VecDeque::pop_front)
|
||||
.unwrap_or_else(|| HttpResponse {
|
||||
status_code: 404,
|
||||
headers: BTreeMap::new(),
|
||||
content_type: None,
|
||||
body: Vec::new(),
|
||||
})
|
||||
};
|
||||
async move { response }
|
||||
});
|
||||
(Self { requests }, handler)
|
||||
}
|
||||
|
||||
fn requests(&self) -> Vec<HttpRequest> {
|
||||
self.requests.lock().expect("request recording").clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn response(body: &str) -> HttpResponse {
|
||||
HttpResponse {
|
||||
status_code: 200,
|
||||
headers: BTreeMap::from([("Content-Length".into(), body.len().to_string())]),
|
||||
content_type: Some("application/json".into()),
|
||||
body: body.as_bytes().to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
fn client_with_fixture(
|
||||
capabilities: &[(&str, &str)],
|
||||
responses: &[(&str, &str)],
|
||||
) -> (GridClient, RecordingHttp) {
|
||||
let (recording, handler) = RecordingHttp::new(capabilities, responses);
|
||||
let mut client = GridClient::new().expect("GridClient constructor");
|
||||
client.set_http_caps_client(
|
||||
HttpCapsClient::new(handler.clone()).expect("HttpCapsClient constructor"),
|
||||
);
|
||||
if !capabilities.is_empty() {
|
||||
let mut simulator_client = GridClient::new().expect("simulator GridClient constructor");
|
||||
simulator_client.set_http_caps_client(
|
||||
HttpCapsClient::new(handler).expect("simulator HttpCapsClient constructor"),
|
||||
);
|
||||
let simulator = Simulator::new(
|
||||
simulator_client,
|
||||
"127.0.0.1:0".parse().expect("loopback endpoint"),
|
||||
0,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.expect("fixture simulator");
|
||||
simulator
|
||||
.set_seed_caps(Some(Uri(SEED_CAPS.into())), Some(true))
|
||||
.expect("seed fixture capabilities");
|
||||
let mut network = client.network();
|
||||
network.set_current_sim(Some(simulator));
|
||||
client.set_network(network);
|
||||
}
|
||||
(client, recording)
|
||||
}
|
||||
|
||||
fn body(request: &HttpRequest) -> String {
|
||||
String::from_utf8(request.body.clone()).expect("UTF-8 request body")
|
||||
}
|
||||
|
||||
fn uuid_eq(actual: &UUID, expected: &UUID) {
|
||||
assert_eq!(
|
||||
actual.get_bytes().expect("actual UUID bytes"),
|
||||
expected.get_bytes().expect("expected UUID bytes")
|
||||
);
|
||||
}
|
||||
|
||||
fn happy_upload_responses<'a>(
|
||||
capability: &'a str,
|
||||
uploader: &'a str,
|
||||
new_asset: &UUID,
|
||||
) -> [(&'a str, String); 2] {
|
||||
[
|
||||
(
|
||||
capability,
|
||||
format!(r#"{{"state":"upload","uploader":"{uploader}"}}"#),
|
||||
),
|
||||
(
|
||||
uploader,
|
||||
format!(
|
||||
r#"{{"state":"complete","new_asset":"{}"}}"#,
|
||||
new_asset.to_string()
|
||||
),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
fn response_refs<'a, const N: usize>(
|
||||
responses: &'a [(&'a str, String); N],
|
||||
) -> Vec<(&'a str, &'a str)> {
|
||||
responses
|
||||
.iter()
|
||||
.map(|(uri, body)| (*uri, body.as_str()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.SetMaterialOverrideAsync_HappyPath_PostsBareArrayWithGltfJson::test 0c51b7b793111f5433e52057f26fa5a98d983e7230fefeb61a7b3408e97f28ee translated
|
||||
#[test]
|
||||
fn set_material_override_posts_bare_array_with_gltf_json() {
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[("ModifyMaterialParams", MODIFY_MATERIAL)],
|
||||
&[(MODIFY_MATERIAL, r#"{"success":true}"#)],
|
||||
);
|
||||
let object_id = UUID::random().expect("UUID Random");
|
||||
let expected_id = object_id.to_string();
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material
|
||||
.set_base_color_factor_with_color4_boolean(
|
||||
Color4::new_with_single_single_single_single(0.1, 0.2, 0.3, 1.0)
|
||||
.expect("Color4 constructor"),
|
||||
Some(true),
|
||||
)
|
||||
.expect("SetBaseColorFactor");
|
||||
let result = block_on(client.objects().set_material_override(
|
||||
client.network().current_sim().expect("current simulator"),
|
||||
object_id,
|
||||
3,
|
||||
material,
|
||||
None,
|
||||
))
|
||||
.expect("SetMaterialOverrideAsync");
|
||||
assert!(result);
|
||||
let requests = recording.requests();
|
||||
assert_eq!(requests.len(), 1);
|
||||
let body = body(&requests[0]);
|
||||
assert!(body.contains("<key>object_id</key>"));
|
||||
assert!(body.contains(&expected_id));
|
||||
assert!(body.contains("<key>side</key>"));
|
||||
assert!(body.contains("<key>gltf_json</key>"));
|
||||
assert!(!body.contains("<key>asset_id</key>"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.ClearMaterialOverrideAsync_SendsEmptyGltfJson::test 8394d063ea71447d9ce2b76fd00be1d10967f9193e1eb909c5b9f2da56eec812 translated
|
||||
#[test]
|
||||
fn clear_material_override_sends_empty_gltf_json() {
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[("ModifyMaterialParams", MODIFY_MATERIAL)],
|
||||
&[(MODIFY_MATERIAL, r#"{"success":true}"#)],
|
||||
);
|
||||
assert!(
|
||||
block_on(client.objects().clear_material_override(
|
||||
client.network().current_sim().expect("current simulator"),
|
||||
UUID::random().expect("UUID Random"),
|
||||
0,
|
||||
None,
|
||||
))
|
||||
.expect("ClearMaterialOverrideAsync")
|
||||
);
|
||||
let body = body(&recording.requests()[0]);
|
||||
assert!(body.contains("<key>gltf_json</key>"));
|
||||
assert!(body.contains("<string />") || body.contains("<string></string>"));
|
||||
assert!(!body.contains("<key>asset_id</key>"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.ApplyMaterialAsync_WithoutOverride_SendsAssetIdOnly::test 1db03ab6710ecf532644398d1fef5e82520e1206058d66fb15c8885fdc8f8363 translated
|
||||
#[test]
|
||||
fn apply_material_without_override_sends_asset_id_only() {
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[("ModifyMaterialParams", MODIFY_MATERIAL)],
|
||||
&[(MODIFY_MATERIAL, r#"{"success":true}"#)],
|
||||
);
|
||||
let asset_id = UUID::random().expect("UUID Random");
|
||||
let expected_id = asset_id.to_string();
|
||||
assert!(
|
||||
block_on(client.objects().apply_material(
|
||||
client.network().current_sim().expect("current simulator"),
|
||||
UUID::random().expect("UUID Random"),
|
||||
1,
|
||||
asset_id,
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("ApplyMaterialAsync")
|
||||
);
|
||||
let body = body(&recording.requests()[0]);
|
||||
assert!(body.contains("<key>asset_id</key>"));
|
||||
assert!(body.contains(&expected_id));
|
||||
assert!(!body.contains("<key>gltf_json</key>"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.SendMaterialUpdatesAsync_MultipleEntries_SendsSingleArrayBody::test 621dca88e7f1c9e024563204ca05c3c8d9a03c4b5a7b31ec1c006abe6732b47b translated
|
||||
#[test]
|
||||
fn material_updates_send_one_array_body() {
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[("ModifyMaterialParams", MODIFY_MATERIAL)],
|
||||
&[(MODIFY_MATERIAL, r#"{"success":true}"#)],
|
||||
);
|
||||
let mut first = GLTFMaterialUpdate::new().expect("GLTFMaterialUpdate constructor");
|
||||
first.set_object_id(UUID::random().expect("UUID Random"));
|
||||
first.set_side(0);
|
||||
let mut second = GLTFMaterialUpdate::new().expect("GLTFMaterialUpdate constructor");
|
||||
second.set_object_id(UUID::random().expect("UUID Random"));
|
||||
second.set_side(1);
|
||||
second.set_asset_id(Some(Some(UUID::random().expect("UUID Random"))));
|
||||
assert!(
|
||||
block_on(client.objects().send_material_updates(
|
||||
client.network().current_sim().expect("current simulator"),
|
||||
Box::new(vec![first, second].into_iter()),
|
||||
None,
|
||||
))
|
||||
.expect("SendMaterialUpdatesAsync")
|
||||
);
|
||||
assert_eq!(recording.requests().len(), 1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.SendMaterialUpdatesAsync_ServerRejects_ReturnsFalse::test e9fbd95fff84695e2cb1a35943bda768f00cf9015b25e0ae1505dce4dde603a4 translated
|
||||
#[test]
|
||||
fn material_updates_server_rejection_returns_false() {
|
||||
let (client, _) = client_with_fixture(
|
||||
&[("ModifyMaterialParams", MODIFY_MATERIAL)],
|
||||
&[(
|
||||
MODIFY_MATERIAL,
|
||||
r#"{"success":false,"message":"no rez rights"}"#,
|
||||
)],
|
||||
);
|
||||
assert!(
|
||||
!block_on(client.objects().clear_material_override(
|
||||
client.network().current_sim().expect("current simulator"),
|
||||
UUID::random().expect("UUID Random"),
|
||||
0,
|
||||
None,
|
||||
))
|
||||
.expect("ClearMaterialOverrideAsync")
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.SendMaterialUpdatesAsync_NoCapability_ReturnsFalseWithoutRequest::test fdceb6bf865cb23386a6b82a9741f230e5c22b0ec6d37bc2ac8478f29292a49f translated
|
||||
#[test]
|
||||
fn material_updates_without_capability_make_no_request() {
|
||||
let (client, recording) = client_with_fixture(&[("SomeOtherCap", OTHER_CAP)], &[]);
|
||||
assert!(
|
||||
!block_on(client.objects().clear_material_override(
|
||||
client.network().current_sim().expect("current simulator"),
|
||||
UUID::random().expect("UUID Random"),
|
||||
0,
|
||||
None,
|
||||
))
|
||||
.expect("ClearMaterialOverrideAsync")
|
||||
);
|
||||
assert!(recording.requests().is_empty());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialUploadTests.cs::GLTFMaterialUploadTests.RequestUpdateMaterialAgentInventoryAsync_HappyPath_PostsMetadataThenJsonAndReturnsNewAsset::test 5ac0e3c27fa6ebfddc9d7582aefb0684a676413948b055382c43b1b0b1cd7e7e translated
|
||||
#[test]
|
||||
fn material_agent_upload_posts_metadata_then_json() {
|
||||
let item_id = UUID::random().expect("UUID Random");
|
||||
let new_asset = UUID::random().expect("UUID Random");
|
||||
let responses = happy_upload_responses(MATERIAL_AGENT, MATERIAL_UPLOADER, &new_asset);
|
||||
let refs = response_refs(&responses);
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[
|
||||
("UpdateMaterialAgentInventory", MATERIAL_AGENT),
|
||||
("UpdateMaterialTaskInventory", MATERIAL_TASK),
|
||||
],
|
||||
&refs,
|
||||
);
|
||||
let result = block_on(client.inventory().request_update_material_agent_inventory(
|
||||
AssetMaterial::new_with_constructor().expect("AssetMaterial constructor"),
|
||||
item_id,
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("RequestUpdateMaterialAgentInventoryAsync");
|
||||
assert!(result.0);
|
||||
uuid_eq(&result.2, &new_asset);
|
||||
let requests = recording.requests();
|
||||
assert_eq!(requests.len(), 2);
|
||||
let metadata = body(&requests[0]);
|
||||
assert!(metadata.contains("<key>item_id</key>"));
|
||||
assert!(!metadata.contains("<key>task_id</key>"));
|
||||
assert_eq!(requests[1].uri, Uri(MATERIAL_UPLOADER.into()));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialUploadTests.cs::GLTFMaterialUploadTests.RequestUpdateMaterialTaskInventoryAsync_HappyPath_PostsItemIdAndTaskId::test 7ac0e7d210b1aefa795e479f4da0d2dd4caae0b3bbe84ca124707c3ae005bbbd translated
|
||||
#[test]
|
||||
fn material_task_upload_posts_item_and_task_ids() {
|
||||
let new_asset = UUID::random().expect("UUID Random");
|
||||
let responses = happy_upload_responses(MATERIAL_TASK, MATERIAL_UPLOADER, &new_asset);
|
||||
let refs = response_refs(&responses);
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[
|
||||
("UpdateMaterialAgentInventory", MATERIAL_AGENT),
|
||||
("UpdateMaterialTaskInventory", MATERIAL_TASK),
|
||||
],
|
||||
&refs,
|
||||
);
|
||||
let result = block_on(client.inventory().request_update_material_task_inventory(
|
||||
AssetMaterial::new_with_constructor().expect("AssetMaterial constructor"),
|
||||
UUID::random().expect("UUID Random"),
|
||||
UUID::random().expect("UUID Random"),
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("RequestUpdateMaterialTaskInventoryAsync");
|
||||
assert!(result.0);
|
||||
uuid_eq(&result.2, &new_asset);
|
||||
let metadata = body(&recording.requests()[0]);
|
||||
assert!(metadata.contains("<key>item_id</key>"));
|
||||
assert!(metadata.contains("<key>task_id</key>"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialUploadTests.cs::GLTFMaterialUploadTests.RequestUpdateMaterialAgentInventoryAsync_NoCapability_Throws::test 325269807d778264e571d1518ca9a2ca69a27ba67ad689e580f2636ab595f335 translated
|
||||
#[test]
|
||||
fn material_agent_upload_without_capability_is_invalid_operation() {
|
||||
let (client, _) = client_with_fixture(&[], &[]);
|
||||
let result = block_on(client.inventory().request_update_material_agent_inventory(
|
||||
AssetMaterial::new_with_constructor().expect("AssetMaterial constructor"),
|
||||
UUID::random().expect("UUID Random"),
|
||||
None,
|
||||
None,
|
||||
));
|
||||
match result {
|
||||
Err(error) => assert_eq!(error, Error::InvalidOperation),
|
||||
Ok(_) => panic!("expected InvalidOperation, got success"),
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GLTFMaterialUploadTests.cs::GLTFMaterialUploadTests.RequestUpdateMaterialAgentInventoryAsync_UploadedJsonRoundTripsMaterial::test fd059dfc8c9299c3b6583b3b47ba18ae9c92e3ad923f88634019b0ab9f34d401 translated
|
||||
#[test]
|
||||
fn uploaded_material_json_round_trips() {
|
||||
let new_asset = UUID::random().expect("UUID Random");
|
||||
let responses = happy_upload_responses(MATERIAL_AGENT, MATERIAL_UPLOADER, &new_asset);
|
||||
let refs = response_refs(&responses);
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[
|
||||
("UpdateMaterialAgentInventory", MATERIAL_AGENT),
|
||||
("UpdateMaterialTaskInventory", MATERIAL_TASK),
|
||||
],
|
||||
&refs,
|
||||
);
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material.set_name("My Material".into());
|
||||
material
|
||||
.set_base_color_factor_with_color4_boolean(
|
||||
Color4::new_with_single_single_single_single(0.2, 0.4, 0.6, 1.0)
|
||||
.expect("Color4 constructor"),
|
||||
None,
|
||||
)
|
||||
.expect("SetBaseColorFactor");
|
||||
block_on(client.inventory().request_update_material_agent_inventory(
|
||||
material,
|
||||
UUID::random().expect("UUID Random"),
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("RequestUpdateMaterialAgentInventoryAsync");
|
||||
let uploaded = recording.requests()[1].body.clone();
|
||||
let round_trip =
|
||||
AssetMaterial::new_with_uuid_bytes(UUID::random().expect("UUID Random"), uploaded)
|
||||
.expect("AssetMaterial JSON constructor");
|
||||
assert_eq!(round_trip.name(), "My Material");
|
||||
assert_eq!(
|
||||
[
|
||||
round_trip.base_color_factor().r,
|
||||
round_trip.base_color_factor().g,
|
||||
round_trip.base_color_factor().b,
|
||||
round_trip.base_color_factor().a,
|
||||
],
|
||||
[0.2, 0.4, 0.6, 1.0]
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.GetTerrainMaterialOverridesAsync_ParsesFourSlotsWithSomeEmpty::test 0b7f2b5a7a95c70f4ed97b9b028f3ec16f1cd427a9d4d1b133523bd331f6b9f2 translated
|
||||
#[test]
|
||||
fn terrain_get_parses_four_slots_with_empty_entries() {
|
||||
let (client, _) = client_with_fixture(
|
||||
&[("ModifyRegion", MODIFY_REGION)],
|
||||
&[(
|
||||
MODIFY_REGION,
|
||||
r#"{"success":true,"overrides":[{},{"mf":0.25},{},{}]}"#,
|
||||
)],
|
||||
);
|
||||
let overrides = block_on(client.terrain().get_terrain_material_overrides(None))
|
||||
.expect("GetTerrainMaterialOverridesAsync")
|
||||
.expect("successful override response");
|
||||
assert_eq!(overrides.len(), 4);
|
||||
assert!(overrides[0].is_none());
|
||||
assert_eq!(
|
||||
overrides[1].as_ref().expect("slot one").metallic_factor(),
|
||||
0.25
|
||||
);
|
||||
assert!(overrides[2].is_none());
|
||||
assert!(overrides[3].is_none());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.GetTerrainMaterialOverridesAsync_ServerReportsFailure_ReturnsNull::test c66b84662333288b7328822d1f9fa79450075d44a1178a9b0b661671072efe5b translated
|
||||
#[test]
|
||||
fn terrain_get_server_failure_returns_none() {
|
||||
let (client, _) = client_with_fixture(
|
||||
&[("ModifyRegion", MODIFY_REGION)],
|
||||
&[(MODIFY_REGION, r#"{"success":false,"message":"nope"}"#)],
|
||||
);
|
||||
assert!(
|
||||
block_on(client.terrain().get_terrain_material_overrides(None))
|
||||
.expect("GetTerrainMaterialOverridesAsync")
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.GetTerrainMaterialOverridesAsync_NoCapability_ReturnsNullWithoutRequest::test 677f80689e1b6a67893d100e1116805fb9f63c5b6ec33e64a4dc9a4cf24c1237 translated
|
||||
#[test]
|
||||
fn terrain_get_without_capability_makes_no_request() {
|
||||
let (client, recording) = client_with_fixture(&[("SomeOtherCap", OTHER_CAP)], &[]);
|
||||
assert!(
|
||||
block_on(client.terrain().get_terrain_material_overrides(None))
|
||||
.expect("GetTerrainMaterialOverridesAsync")
|
||||
.is_none()
|
||||
);
|
||||
assert!(recording.requests().is_empty());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.SetTerrainMaterialOverridesAsync_MixOfNullAndSet_PostsFourEntries::test a4ce031e565ca7eb1864064d299dbf0c7b715581ce330a57be9c3aa93987e67c translated
|
||||
#[test]
|
||||
fn terrain_set_posts_four_mixed_entries() {
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[("ModifyRegion", MODIFY_REGION)],
|
||||
&[(MODIFY_REGION, r#"{"success":true}"#)],
|
||||
);
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material
|
||||
.set_roughness_factor_with_single_boolean(0.1, Some(true))
|
||||
.expect("SetRoughnessFactor");
|
||||
assert!(
|
||||
block_on(
|
||||
client
|
||||
.terrain()
|
||||
.set_terrain_material_overrides(vec![None, Some(material), None, None], None,)
|
||||
)
|
||||
.expect("SetTerrainMaterialOverridesAsync")
|
||||
);
|
||||
let body = body(&recording.requests()[0]);
|
||||
assert!(body.contains("<key>overrides</key>"));
|
||||
assert!(body.contains("<key>rf</key>"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.SetTerrainMaterialOverridesAsync_WrongLength_Throws::test 836099a369b37555049b1c1ddfb9562c57cdef88381b7a79e8b80fe62b169a44 translated
|
||||
#[test]
|
||||
fn terrain_set_wrong_length_is_argument_error() {
|
||||
let (client, _) = client_with_fixture(&[("ModifyRegion", MODIFY_REGION)], &[]);
|
||||
let result = block_on(
|
||||
client
|
||||
.terrain()
|
||||
.set_terrain_material_overrides(vec![None, None], None),
|
||||
);
|
||||
match result {
|
||||
Err(error) => assert_eq!(error, Error::Argument),
|
||||
Ok(_) => panic!("expected Argument, got success"),
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.SetTerrainMaterialOverridesAsync_NoCapability_ReturnsFalseWithoutRequest::test 37948cbc0240910d63782d88c0fb9f1d239215cea34a5aa84ac68a10d0555e87 translated
|
||||
#[test]
|
||||
fn terrain_set_without_capability_makes_no_request() {
|
||||
let (client, recording) = client_with_fixture(&[("SomeOtherCap", OTHER_CAP)], &[]);
|
||||
assert!(
|
||||
!block_on(
|
||||
client
|
||||
.terrain()
|
||||
.set_terrain_material_overrides(vec![None, None, None, None], None,)
|
||||
)
|
||||
.expect("SetTerrainMaterialOverridesAsync")
|
||||
);
|
||||
assert!(recording.requests().is_empty());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/SendPostcardTests.cs::SendPostcardTests.SendPostcardAsync_HappyPath_PostsMetadataThenImageAndReturnsTrue::test 2e02bd16ef1431c2ca82d7804dffc764be0175cff5daff8c38d0a61641439e06 translated
|
||||
#[test]
|
||||
fn postcard_posts_metadata_then_image() {
|
||||
let (mut client, recording) = client_with_fixture(
|
||||
&[("SendPostcard", POSTCARD)],
|
||||
&[
|
||||
(
|
||||
POSTCARD,
|
||||
r#"{"state":"upload","uploader":"http://test.invalid/send-postcard/upload/abc123"}"#,
|
||||
),
|
||||
(POSTCARD_UPLOADER, r#"{"state":"complete"}"#),
|
||||
],
|
||||
);
|
||||
assert!(
|
||||
block_on(client.self_().send_postcard(
|
||||
vec![0xff, 0xd8, 0xff, 0xd9],
|
||||
"friend@example.com".into(),
|
||||
"Jim Radford".into(),
|
||||
"Postcard from the edge".into(),
|
||||
"Hello, how are you today?".into(),
|
||||
Vector3::one(),
|
||||
None,
|
||||
))
|
||||
.expect("SendPostcardAsync")
|
||||
);
|
||||
let requests = recording.requests();
|
||||
assert_eq!(requests.len(), 2);
|
||||
assert_eq!(requests[0].method, "POST");
|
||||
assert_eq!(requests[0].uri, Uri(POSTCARD.into()));
|
||||
let metadata = body(&requests[0]);
|
||||
assert!(!metadata.contains("<key>from</key>"));
|
||||
for field in ["to", "name", "subject", "msg", "pos-global"] {
|
||||
assert!(metadata.contains(field));
|
||||
}
|
||||
assert_eq!(requests[1].method, "POST");
|
||||
assert_eq!(requests[1].uri, Uri(POSTCARD_UPLOADER.into()));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/SendPostcardTests.cs::SendPostcardTests.SendPostcardAsync_UploaderMissingFromResponse_ReturnsFalseWithoutSecondRequest::test 2f9498d57d7a512399f9b108765e6e8da8e4c937402f9671d580c66332630432 translated
|
||||
#[test]
|
||||
fn postcard_missing_uploader_returns_false_after_one_request() {
|
||||
let (mut client, recording) = client_with_fixture(
|
||||
&[("SendPostcard", POSTCARD)],
|
||||
&[(POSTCARD, r#"{"state":"upload"}"#)],
|
||||
);
|
||||
assert!(
|
||||
!block_on(client.self_().send_postcard(
|
||||
vec![1, 2, 3],
|
||||
"friend@example.com".into(),
|
||||
"Jim Radford".into(),
|
||||
"Subject".into(),
|
||||
"Message".into(),
|
||||
Vector3::zero(),
|
||||
None,
|
||||
))
|
||||
.expect("SendPostcardAsync")
|
||||
);
|
||||
assert_eq!(recording.requests().len(), 1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/SendPostcardTests.cs::SendPostcardTests.SendPostcardAsync_UploadDoesNotComplete_ReturnsFalse::test 937b682b406506ec9fba9570852bbf8689450a11cbecb85979af97609b1794f9 translated
|
||||
#[test]
|
||||
fn postcard_incomplete_upload_returns_false() {
|
||||
let (mut client, _) = client_with_fixture(
|
||||
&[("SendPostcard", POSTCARD)],
|
||||
&[
|
||||
(
|
||||
POSTCARD,
|
||||
r#"{"state":"upload","uploader":"http://test.invalid/send-postcard/upload/abc123"}"#,
|
||||
),
|
||||
(POSTCARD_UPLOADER, r#"{"state":"failed"}"#),
|
||||
],
|
||||
);
|
||||
assert!(
|
||||
!block_on(client.self_().send_postcard(
|
||||
vec![1, 2, 3],
|
||||
"friend@example.com".into(),
|
||||
"Jim Radford".into(),
|
||||
"Subject".into(),
|
||||
"Message".into(),
|
||||
Vector3::zero(),
|
||||
None,
|
||||
))
|
||||
.expect("SendPostcardAsync")
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/SendPostcardTests.cs::SendPostcardTests.SendPostcardAsync_NoCapability_ReturnsFalseWithoutRequest::test 8d3ef84e873096d9388bb7db3eaeeb79c661fd9951e338f71bbf3251ae6580e8 translated
|
||||
#[test]
|
||||
fn postcard_without_capability_makes_no_request() {
|
||||
let (mut client, recording) = client_with_fixture(&[], &[]);
|
||||
assert!(
|
||||
!block_on(client.self_().send_postcard(
|
||||
vec![1, 2, 3],
|
||||
"friend@example.com".into(),
|
||||
"Jim Radford".into(),
|
||||
"Subject".into(),
|
||||
"Message".into(),
|
||||
Vector3::zero(),
|
||||
None,
|
||||
))
|
||||
.expect("SendPostcardAsync")
|
||||
);
|
||||
assert!(recording.requests().is_empty());
|
||||
}
|
||||
|
||||
fn thumbnail_responses(new_asset: &UUID) -> [(&str, String); 2] {
|
||||
[
|
||||
(
|
||||
THUMBNAIL,
|
||||
format!(r#"{{"uploader":"{THUMBNAIL_UPLOADER}"}}"#),
|
||||
),
|
||||
(
|
||||
THUMBNAIL_UPLOADER,
|
||||
format!(
|
||||
r#"{{"state":"complete","new_asset":"{}"}}"#,
|
||||
new_asset.to_string()
|
||||
),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_AgentInventoryItem_SendsBareItemIdAndReturnsNewAsset::test 40ca874a37dade3bfbb391a2b4a75c684cfd7509b269286ccc14d747340d095d translated
|
||||
#[test]
|
||||
fn thumbnail_agent_item_sends_bare_item_id() {
|
||||
let new_asset = UUID::random().expect("UUID Random");
|
||||
let responses = thumbnail_responses(&new_asset);
|
||||
let refs = response_refs(&responses);
|
||||
let (client, recording) =
|
||||
client_with_fixture(&[("InventoryThumbnailUpload", THUMBNAIL)], &refs);
|
||||
let item_id = UUID::random().expect("UUID Random");
|
||||
let result = block_on(client.inventory().upload_thumbnail(
|
||||
item_id,
|
||||
UUID::zero(),
|
||||
vec![1, 2, 3],
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("UploadThumbnailAsync")
|
||||
.flatten()
|
||||
.expect("new thumbnail asset");
|
||||
uuid_eq(&result, &new_asset);
|
||||
let requests = recording.requests();
|
||||
assert_eq!(requests.len(), 2);
|
||||
let metadata = body(&requests[0]);
|
||||
assert!(metadata.contains("<key>item_id</key>"));
|
||||
assert!(!metadata.contains("<key>task_id</key>"));
|
||||
assert!(!metadata.contains("<key>category_id</key>"));
|
||||
assert_eq!(requests[1].uri, Uri(THUMBNAIL_UPLOADER.into()));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_TaskInventoryItem_SendsItemIdAndTaskId::test dae80f9a7ba6222a651165f779c123d8472f88a17490e69a1112acc3cec6d108 translated
|
||||
#[test]
|
||||
fn thumbnail_task_item_sends_item_and_task_ids() {
|
||||
let new_asset = UUID::random().expect("UUID Random");
|
||||
let responses = thumbnail_responses(&new_asset);
|
||||
let refs = response_refs(&responses);
|
||||
let (client, recording) =
|
||||
client_with_fixture(&[("InventoryThumbnailUpload", THUMBNAIL)], &refs);
|
||||
let item_id = UUID::random().expect("UUID Random");
|
||||
let task_id = UUID::random().expect("UUID Random");
|
||||
let result =
|
||||
block_on(
|
||||
client
|
||||
.inventory()
|
||||
.upload_thumbnail(item_id, task_id, vec![1, 2, 3], None, None),
|
||||
)
|
||||
.expect("UploadThumbnailAsync")
|
||||
.flatten()
|
||||
.expect("new thumbnail asset");
|
||||
uuid_eq(&result, &new_asset);
|
||||
let metadata = body(&recording.requests()[0]);
|
||||
assert!(metadata.contains("<key>item_id</key>"));
|
||||
assert!(metadata.contains("<key>task_id</key>"));
|
||||
assert!(!metadata.contains("<key>category_id</key>"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_KnownLocalFolder_SendsCategoryId::test 1ccca44bbead54fd5041c41fc6560478ba17f9e5d9bacff21096b254d2f526db translated
|
||||
#[test]
|
||||
fn thumbnail_known_local_folder_sends_category_id() {
|
||||
let folder_id = UUID::random().expect("UUID Random");
|
||||
let new_asset = UUID::random().expect("UUID Random");
|
||||
let responses = thumbnail_responses(&new_asset);
|
||||
let refs = response_refs(&responses);
|
||||
let (client, recording) =
|
||||
client_with_fixture(&[("InventoryThumbnailUpload", THUMBNAIL)], &refs);
|
||||
let mut folder = InventoryFolder::new(folder_id).expect("InventoryFolder constructor");
|
||||
folder.base.set_name("Test Folder".into());
|
||||
folder.base.set_parent_uuid(UUID::zero());
|
||||
let mut store = client.inventory().store().expect("fixture inventory store");
|
||||
store.set_item(folder_id, folder.base);
|
||||
let result = block_on(client.inventory().upload_thumbnail(
|
||||
folder_id,
|
||||
UUID::zero(),
|
||||
vec![1, 2, 3],
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("UploadThumbnailAsync")
|
||||
.flatten()
|
||||
.expect("new thumbnail asset");
|
||||
uuid_eq(&result, &new_asset);
|
||||
let metadata = body(&recording.requests()[0]);
|
||||
assert!(metadata.contains("<key>category_id</key>"));
|
||||
assert!(!metadata.contains("<key>item_id</key>"));
|
||||
assert!(!metadata.contains("<key>task_id</key>"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_NoCapability_ReturnsNullWithoutRequest::test 2bc1ad18b159c5d62a18d2208ed3cf3c88d3f666a0e0dad8730778cd22b59eda translated
|
||||
#[test]
|
||||
fn thumbnail_without_capability_makes_no_request() {
|
||||
let (client, recording) = client_with_fixture(&[], &[]);
|
||||
let result = block_on(client.inventory().upload_thumbnail(
|
||||
UUID::random().expect("UUID Random"),
|
||||
UUID::zero(),
|
||||
vec![1],
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("UploadThumbnailAsync")
|
||||
.flatten();
|
||||
assert!(result.is_none());
|
||||
assert!(recording.requests().is_empty());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_MetadataResponseMissingUploader_ReturnsNullWithoutSecondRequest::test 8db3eddf1204ad795e9d5ef15365f422f96191a8b4c24ef3393b03c10d92d662 translated
|
||||
#[test]
|
||||
fn thumbnail_missing_uploader_returns_none_after_one_request() {
|
||||
let (client, recording) = client_with_fixture(
|
||||
&[("InventoryThumbnailUpload", THUMBNAIL)],
|
||||
&[(THUMBNAIL, r#"{"state":"upload"}"#)],
|
||||
);
|
||||
let result = block_on(client.inventory().upload_thumbnail(
|
||||
UUID::random().expect("UUID Random"),
|
||||
UUID::zero(),
|
||||
vec![1],
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("UploadThumbnailAsync")
|
||||
.flatten();
|
||||
assert!(result.is_none());
|
||||
assert_eq!(recording.requests().len(), 1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_UploadDoesNotComplete_ReturnsNull::test e870f6913e3f45676ce490069930427e6c625072fc1d6ebbf16f503be51df4ae translated
|
||||
#[test]
|
||||
fn thumbnail_incomplete_upload_returns_none() {
|
||||
let (client, _) = client_with_fixture(
|
||||
&[("InventoryThumbnailUpload", THUMBNAIL)],
|
||||
&[
|
||||
(
|
||||
THUMBNAIL,
|
||||
r#"{"uploader":"http://test.invalid/inventory-thumbnail-upload/upload/abc123"}"#,
|
||||
),
|
||||
(
|
||||
THUMBNAIL_UPLOADER,
|
||||
r#"{"state":"failed","message":"bad image"}"#,
|
||||
),
|
||||
],
|
||||
);
|
||||
let result = block_on(client.inventory().upload_thumbnail(
|
||||
UUID::random().expect("UUID Random"),
|
||||
UUID::zero(),
|
||||
vec![1],
|
||||
None,
|
||||
None,
|
||||
))
|
||||
.expect("UploadThumbnailAsync")
|
||||
.flatten();
|
||||
assert!(result.is_none());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.AssetManager_Null_Throws::test 4fa1be8b233dacf6a5955359f2197ff77ae85ffbf2c3c68fcd8cbe672c2c5f91 translated
|
||||
#[test]
|
||||
fn asset_manager_none_client_is_argument_null() {
|
||||
match AssetManager::new(None) {
|
||||
Err(error) => assert_eq!(error, Error::ArgumentNull),
|
||||
Ok(_) => panic!("expected ArgumentNull, got success"),
|
||||
}
|
||||
}
|
||||
516
tests/compat/tests/asset_document_semantics.rs
Normal file
516
tests/compat/tests/asset_document_semantics.rs
Normal file
@@ -0,0 +1,516 @@
|
||||
#![allow(clippy::float_cmp)]
|
||||
|
||||
// Exact BSD-3-Clause fixture provenance at LibreMetaverse
|
||||
// 2aa70bb68513b39795da5d13c88f31b86e85a3ba (see LICENSE.md):
|
||||
// AssetMaterialOverrideTests.cs 3ec3a8bca08da06c52de1eeea1428b2b83c27660af20580f0333ed67b01bd09b
|
||||
// GltfDocumentTests.cs e6e94d5b97a27b8cc4a345f08ab9a9a43b6ce587667edd89d8a4ebbc04eaa646
|
||||
// Embedded 44-byte triangle buffer d3478e66e380d8a2b0c9d80f3459f75660efb111e7b801a7d1c1f8f48723d79b
|
||||
|
||||
use libremetaverse::assets::gltf::{GltfDocument, GltfPrimitive, GltfPrimitiveMode};
|
||||
use libremetaverse::assets::{AssetMaterial, GltfAlphaMode};
|
||||
use libremetaverse_structured_data::OSDMap;
|
||||
use libremetaverse_types::{Color4, Quaternion, UUID, Vector2, Vector3};
|
||||
|
||||
fn color(r: f32, g: f32, b: f32, a: f32) -> Color4 {
|
||||
Color4::new_with_single_single_single_single(r, g, b, a).expect("Color4 constructor")
|
||||
}
|
||||
|
||||
fn vector2(x: f32, y: f32) -> Vector2 {
|
||||
Vector2::new_with_single_single(x, y).expect("Vector2 constructor")
|
||||
}
|
||||
|
||||
fn color_values(value: &Color4) -> [f32; 4] {
|
||||
[value.r, value.g, value.b, value.a]
|
||||
}
|
||||
|
||||
fn vector2_values(value: &Vector2) -> [f32; 2] {
|
||||
[value.x, value.y]
|
||||
}
|
||||
|
||||
fn vector3_values(value: &Vector3) -> [f32; 3] {
|
||||
[value.x, value.y, value.z]
|
||||
}
|
||||
|
||||
fn quaternion_values(value: &Quaternion) -> [f32; 4] {
|
||||
[value.x, value.y, value.z, value.w]
|
||||
}
|
||||
|
||||
fn uuid_eq(actual: &UUID, expected: &UUID) {
|
||||
assert_eq!(
|
||||
actual.get_bytes().expect("actual UUID bytes"),
|
||||
expected.get_bytes().expect("expected UUID bytes")
|
||||
);
|
||||
}
|
||||
|
||||
fn minimal_gltf_json() -> String {
|
||||
r#"{
|
||||
"asset": { "version": "2.0", "generator": "Test" },
|
||||
"scene": 0,
|
||||
"scenes": [{ "name": "Scene", "nodes": [0] }],
|
||||
"nodes": [{ "name": "Mesh", "mesh": 0 }],
|
||||
"meshes": [{
|
||||
"name": "Triangle",
|
||||
"primitives": [{
|
||||
"attributes": { "POSITION": 0 },
|
||||
"indices": 1,
|
||||
"material": 0,
|
||||
"mode": 4
|
||||
}]
|
||||
}],
|
||||
"materials": [{
|
||||
"name": "Mat",
|
||||
"pbrMetallicRoughness": {
|
||||
"baseColorFactor": [1.0, 0.5, 0.0, 1.0],
|
||||
"metallicFactor": 0.0,
|
||||
"roughnessFactor": 1.0
|
||||
},
|
||||
"alphaMode": "OPAQUE",
|
||||
"alphaCutoff": 0.5,
|
||||
"doubleSided": false
|
||||
}],
|
||||
"accessors": [
|
||||
{
|
||||
"bufferView": 0,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 3,
|
||||
"type": "VEC3",
|
||||
"max": [1.0, 1.0, 0.0],
|
||||
"min": [0.0, 0.0, 0.0]
|
||||
},
|
||||
{
|
||||
"bufferView": 1,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5123,
|
||||
"count": 3,
|
||||
"type": "SCALAR"
|
||||
}
|
||||
],
|
||||
"bufferViews": [
|
||||
{ "buffer": 0, "byteOffset": 0, "byteLength": 36, "target": 34962 },
|
||||
{ "buffer": 0, "byteOffset": 36, "byteLength": 6, "target": 34963 }
|
||||
],
|
||||
"buffers": [{
|
||||
"byteLength": 44,
|
||||
"uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAABAAIAAAA="
|
||||
}]
|
||||
}"#
|
||||
.into()
|
||||
}
|
||||
|
||||
fn load_document() -> GltfDocument {
|
||||
GltfDocument::load_gltf(minimal_gltf_json(), None).expect("GltfDocument LoadGltf")
|
||||
}
|
||||
|
||||
fn first_primitive(document: &GltfDocument) -> GltfPrimitive {
|
||||
document.meshes()[0]
|
||||
.primitives()
|
||||
.into_iter()
|
||||
.next()
|
||||
.expect("first primitive")
|
||||
}
|
||||
|
||||
fn assert_close(actual: f32, expected: f32, tolerance: f32) {
|
||||
assert!((actual - expected).abs() <= tolerance);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetBaseColorFactor_OverrideToDefault_IsNudgedOffDefault::test df553fd4df83e48d4dd74cdd8aa15a737ea3a416bcad802f7110bbfe79928a31 translated
|
||||
#[test]
|
||||
fn base_color_override_to_default_is_nudged() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
let default = AssetMaterial::default().base_color_factor();
|
||||
material
|
||||
.set_base_color_factor_with_color4_boolean(default, Some(true))
|
||||
.expect("SetBaseColorFactor");
|
||||
assert_ne!(
|
||||
color_values(&material.base_color_factor()),
|
||||
color_values(&AssetMaterial::default().base_color_factor())
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetBaseColorFactor_NotOverride_LeavesExactDefaultUnchanged::test fec94fcfac0f36cc5813ed087a30e04fcc9815bc02072ea3f5dd282b8698a89c translated
|
||||
#[test]
|
||||
fn base_color_non_override_keeps_default() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
let default = AssetMaterial::default().base_color_factor();
|
||||
material
|
||||
.set_base_color_factor_with_color4_boolean(default, None)
|
||||
.expect("SetBaseColorFactor");
|
||||
assert_eq!(
|
||||
color_values(&material.base_color_factor()),
|
||||
color_values(&AssetMaterial::default().base_color_factor())
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetMetallicFactor_OverrideToOne_ClampsBelowDefault::test 7fcee795160428082f6e579881867c7b6c83f31549077fc28a46d18c75c485c9 translated
|
||||
#[test]
|
||||
fn metallic_override_to_one_clamps_below_default() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material
|
||||
.set_metallic_factor_with_single_boolean(1.0, Some(true))
|
||||
.expect("SetMetallicFactor");
|
||||
assert!(material.metallic_factor() < 1.0);
|
||||
assert_ne!(
|
||||
material.metallic_factor(),
|
||||
AssetMaterial::default().metallic_factor()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetAlphaMode_OverrideToDefaultOpaque_SetsOverrideFlag::test 8af09d12a58083657e27e285802bb3a6a1d1c136397cea53865d964006343715 translated
|
||||
#[test]
|
||||
fn alpha_mode_override_sets_flag() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material
|
||||
.set_alpha_mode_with_gltf_alpha_mode_boolean(GltfAlphaMode::Opaque, Some(true))
|
||||
.expect("SetAlphaMode");
|
||||
assert!(material.override_alpha_mode());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetTextureId_OverrideToNull_UsesSentinelUuid::test d9ebf410d2a55c3619b99524a571396fb268e5edd41de955cb86e4ec8cc55c78 translated
|
||||
#[test]
|
||||
fn null_texture_override_uses_sentinel() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material
|
||||
.set_texture_id(AssetMaterial::TEXTURE_BASE_COLOR, UUID::zero(), Some(true))
|
||||
.expect("SetTextureId");
|
||||
uuid_eq(
|
||||
&material.texture_ids()[AssetMaterial::TEXTURE_BASE_COLOR as usize],
|
||||
&AssetMaterial::gltf_override_null_uuid(),
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ApplyOverride_SentinelTexture_ClearsBaseTexture::test 17fd8cdb12ed5d1d0aa1b0a05dbcc357f75aa350d5079b066c957da459d9f628 translated
|
||||
#[test]
|
||||
fn sentinel_override_clears_base_texture() {
|
||||
let mut base = AssetMaterial::new_with_constructor().expect("base material");
|
||||
base.set_texture_id(
|
||||
AssetMaterial::TEXTURE_BASE_COLOR,
|
||||
UUID::random().expect("UUID Random"),
|
||||
None,
|
||||
)
|
||||
.expect("base texture");
|
||||
let mut override_ = AssetMaterial::new_with_constructor().expect("override material");
|
||||
override_
|
||||
.set_texture_id(AssetMaterial::TEXTURE_BASE_COLOR, UUID::zero(), Some(true))
|
||||
.expect("override texture");
|
||||
base.apply_override(override_).expect("ApplyOverride");
|
||||
uuid_eq(
|
||||
&base.texture_ids()[AssetMaterial::TEXTURE_BASE_COLOR as usize],
|
||||
&UUID::zero(),
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ApplyOverride_UntouchedTexture_LeavesBaseTextureAlone::test 80ec5e369e3682d92ec6996841b15bda38a3ef6edcd36a2fd9893d8c15459348 translated
|
||||
#[test]
|
||||
fn untouched_override_keeps_base_texture() {
|
||||
let original = UUID::random().expect("UUID Random");
|
||||
let original_copy = UUID::new_with_bytes_int32(original.get_bytes().expect("UUID bytes"), 0)
|
||||
.expect("UUID copy");
|
||||
let mut base = AssetMaterial::new_with_constructor().expect("base material");
|
||||
base.set_texture_id(AssetMaterial::TEXTURE_BASE_COLOR, original, None)
|
||||
.expect("base texture");
|
||||
let override_ = AssetMaterial::new_with_constructor().expect("override material");
|
||||
base.apply_override(override_).expect("ApplyOverride");
|
||||
uuid_eq(
|
||||
&base.texture_ids()[AssetMaterial::TEXTURE_BASE_COLOR as usize],
|
||||
&original_copy,
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ApplyOverride_ChangedScalar_ReplacesBaseValue::test 4c305c54c4e451932fbd4a4719957f92f38a7f7d28259559b43cb95fcf9250d1 translated
|
||||
#[test]
|
||||
fn changed_scalar_override_replaces_base() {
|
||||
let mut base = AssetMaterial::new_with_constructor().expect("base material");
|
||||
let mut override_ = AssetMaterial::new_with_constructor().expect("override material");
|
||||
override_
|
||||
.set_roughness_factor_with_single_boolean(0.3, Some(true))
|
||||
.expect("SetRoughnessFactor");
|
||||
base.apply_override(override_).expect("ApplyOverride");
|
||||
assert_eq!(base.roughness_factor(), 0.3);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetBaseMaterial_ResetsFieldsButKeepsTransforms::test 39312602e736fd8607a41d9e6b6348bfaf6e659cf3f63100ee15edd20b672306 translated
|
||||
#[test]
|
||||
fn set_base_material_keeps_texture_transforms() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material.set_name("Foo".into());
|
||||
material
|
||||
.set_roughness_factor_with_single_boolean(0.2, Some(true))
|
||||
.expect("SetRoughnessFactor");
|
||||
material
|
||||
.set_texture_offset(AssetMaterial::TEXTURE_BASE_COLOR, vector2(0.5, 0.25))
|
||||
.expect("SetTextureOffset");
|
||||
material.set_base_material().expect("SetBaseMaterial");
|
||||
assert_eq!(material.name(), "");
|
||||
assert_eq!(
|
||||
material.roughness_factor(),
|
||||
AssetMaterial::default().roughness_factor()
|
||||
);
|
||||
assert_eq!(
|
||||
vector2_values(
|
||||
&material.texture_transforms()[AssetMaterial::TEXTURE_BASE_COLOR as usize].offset,
|
||||
),
|
||||
vector2_values(&vector2(0.5, 0.25))
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ToOverrideOsd_RoundTrip_PreservesOverriddenFields::test 8d542528a14e3b4dcb74ea8a940a44673aada51f98baf8abcdd59a06f36e3cb0 translated
|
||||
#[test]
|
||||
fn override_osd_round_trip_preserves_fields() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material
|
||||
.set_roughness_factor_with_single_boolean(0.4, Some(true))
|
||||
.expect("SetRoughnessFactor");
|
||||
material
|
||||
.set_metallic_factor_with_single_boolean(0.6, Some(true))
|
||||
.expect("SetMetallicFactor");
|
||||
let texture = UUID::random().expect("UUID Random");
|
||||
let expected =
|
||||
UUID::new_with_bytes_int32(texture.get_bytes().expect("UUID bytes"), 0).expect("UUID copy");
|
||||
material
|
||||
.set_texture_id(AssetMaterial::TEXTURE_EMISSIVE, texture, Some(true))
|
||||
.expect("SetTextureId");
|
||||
material
|
||||
.set_texture_rotation(AssetMaterial::TEXTURE_EMISSIVE, 1.25)
|
||||
.expect("SetTextureRotation");
|
||||
let osd = material.to_override_osd().expect("ToOverrideOsd");
|
||||
let round_trip = AssetMaterial::from_override_osd(osd).expect("FromOverrideOsd");
|
||||
assert_eq!(round_trip.roughness_factor(), 0.4);
|
||||
assert_eq!(round_trip.metallic_factor(), 0.6);
|
||||
uuid_eq(
|
||||
&round_trip.texture_ids()[AssetMaterial::TEXTURE_EMISSIVE as usize],
|
||||
&expected,
|
||||
);
|
||||
assert_eq!(
|
||||
round_trip.texture_transforms()[AssetMaterial::TEXTURE_EMISSIVE as usize].rotation,
|
||||
1.25
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ToOverrideOsd_UntouchedMaterial_ProducesEmptyMap::test c9e29f7ec0e6b28579e0499e3ec89841e01a313a9386ba60257e5e701129b1c2 translated
|
||||
#[test]
|
||||
fn untouched_material_override_osd_is_empty() {
|
||||
let material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
let osd: OSDMap = material.to_override_osd().expect("ToOverrideOsd");
|
||||
assert_eq!(osd.count(), 0);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ToOverrideOsd_OverrideToDefaultRoughness_StillEncodesField::test 4ea9920c6709bd29858a8da66313fcee5ebebd646743c5d822dd6c9e477bf3b4 translated
|
||||
#[test]
|
||||
fn default_roughness_override_is_encoded() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material
|
||||
.set_roughness_factor_with_single_boolean(
|
||||
AssetMaterial::default().roughness_factor(),
|
||||
Some(true),
|
||||
)
|
||||
.expect("SetRoughnessFactor");
|
||||
let osd = material.to_override_osd().expect("ToOverrideOsd");
|
||||
assert!(osd.contains_key("rf".into()).expect("ContainsKey"));
|
||||
let round_trip = AssetMaterial::from_override_osd(osd).expect("FromOverrideOsd");
|
||||
assert_ne!(
|
||||
round_trip.roughness_factor(),
|
||||
AssetMaterial::default().roughness_factor()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ToJson_RoundTrip_PreservesNameAndColor::test d7ae4270d82671a970fc1b6457292860d24481dd84e9fb919ae60fded5f1914e translated
|
||||
#[test]
|
||||
fn material_json_round_trip_preserves_name_and_color() {
|
||||
let mut material = AssetMaterial::new_with_constructor().expect("AssetMaterial constructor");
|
||||
material.set_name("Chrome".into());
|
||||
material
|
||||
.set_base_color_factor_with_color4_boolean(color(0.1, 0.2, 0.3, 1.0), None)
|
||||
.expect("SetBaseColorFactor");
|
||||
let json = material.to_json().expect("AssetMaterial ToJson");
|
||||
let decoded =
|
||||
AssetMaterial::new_with_uuid_bytes(UUID::random().expect("UUID Random"), json.into_bytes())
|
||||
.expect("AssetMaterial bytes constructor");
|
||||
assert_eq!(decoded.name(), "Chrome");
|
||||
assert_eq!(
|
||||
color_values(&decoded.base_color_factor()),
|
||||
color_values(&material.base_color_factor())
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.LoadGltf_ParsesSceneGraph::test e20583d8de31f793d1dc49d1dfde89e1eb8c00186359e7df4184e862ec9ed649 translated
|
||||
#[test]
|
||||
fn gltf_parses_scene_graph() {
|
||||
let document = load_document();
|
||||
assert_eq!(document.version(), "2.0");
|
||||
assert_eq!(document.generator().as_deref(), Some("Test"));
|
||||
assert_eq!(document.default_scene(), 0);
|
||||
assert_eq!(document.scenes().len(), 1);
|
||||
assert_eq!(document.scenes()[0].nodes().len(), 1);
|
||||
assert_eq!(document.nodes().len(), 1);
|
||||
assert_eq!(document.nodes()[0].mesh(), 0);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.LoadGltf_ParsesMeshAndPrimitive::test ef6a76308db1966423c7746f5414f3d0553587efc388bbedb962f38cc122ecaf translated
|
||||
#[test]
|
||||
fn gltf_parses_mesh_and_primitive() {
|
||||
let document = load_document();
|
||||
assert_eq!(document.meshes().len(), 1);
|
||||
assert_eq!(document.meshes()[0].name().as_deref(), Some("Triangle"));
|
||||
assert_eq!(document.meshes()[0].primitives().len(), 1);
|
||||
let primitive = first_primitive(&document);
|
||||
assert!(primitive.attributes().contains_key("POSITION"));
|
||||
assert_eq!(primitive.indices(), 1);
|
||||
assert_eq!(primitive.material(), 0);
|
||||
assert_eq!(primitive.mode(), GltfPrimitiveMode::Triangles);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.LoadGltf_ParsesMaterial::test 0147b4d7102c5223f247f69fa4cf3daeb0aa6300ad46ef34d6a17163b694c13e translated
|
||||
#[test]
|
||||
fn gltf_parses_material() {
|
||||
let document = load_document();
|
||||
assert_eq!(document.materials().len(), 1);
|
||||
let material = &document.materials()[0];
|
||||
assert_eq!(material.name().as_deref(), Some("Mat"));
|
||||
assert_close(material.base_color_factor().r, 1.0, 1e-4);
|
||||
assert_close(material.base_color_factor().g, 0.5, 1e-4);
|
||||
assert_close(material.metallic_factor(), 0.0, 1e-4);
|
||||
assert_close(material.roughness_factor(), 1.0, 1e-4);
|
||||
assert_eq!(material.alpha_mode(), GltfAlphaMode::Opaque);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.GetPositions_ReturnsCorrectTriangle::test c3d444122ab73794a011d5a5aafb0c2aa030975393f967e871dc88db200f5e96 translated
|
||||
#[test]
|
||||
fn gltf_positions_are_correct_triangle() {
|
||||
let document = load_document();
|
||||
let positions = document
|
||||
.get_positions(first_primitive(&document))
|
||||
.expect("GetPositions");
|
||||
assert_eq!(positions.len(), 3);
|
||||
assert_eq!(
|
||||
vector3_values(&positions[0]),
|
||||
vector3_values(&Vector3::zero())
|
||||
);
|
||||
assert_close(positions[1].x, 1.0, 1e-5);
|
||||
assert_close(positions[1].y, 0.0, 1e-5);
|
||||
assert_close(positions[2].x, 0.0, 1e-5);
|
||||
assert_close(positions[2].y, 1.0, 1e-5);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.GetIndices_ReturnsCorrectValues::test fa39e87a3dfee7258d9a95907a97cbb107f5add7d6a6f9d9800249bb67e2fc58 translated
|
||||
#[test]
|
||||
fn gltf_indices_are_correct() {
|
||||
let document = load_document();
|
||||
let indices = document
|
||||
.get_indices(first_primitive(&document))
|
||||
.expect("GetIndices");
|
||||
assert_eq!(indices, [0, 1, 2]);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.GetPositions_EmptyWhenNoAttribute::test 06c691911ee6933f1884f6540d69afafa1f272acfed827c628580438204d9b4b translated
|
||||
#[test]
|
||||
fn gltf_positions_empty_without_attribute() {
|
||||
let document = load_document();
|
||||
let primitive = GltfPrimitive::new().expect("GltfPrimitive constructor");
|
||||
assert_eq!(
|
||||
document
|
||||
.get_positions(primitive)
|
||||
.expect("GetPositions")
|
||||
.len(),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.GetNormals_EmptyWhenNoAttribute::test e04480b0b9e23cb561cc55e744ebd85203c759f98ad69febeeb291919f0d91af translated
|
||||
#[test]
|
||||
fn gltf_normals_empty_without_attribute() {
|
||||
let document = load_document();
|
||||
assert_eq!(
|
||||
document
|
||||
.get_normals(first_primitive(&document))
|
||||
.expect("GetNormals")
|
||||
.len(),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.ToJson_RoundTrip_PreservesSceneGraph::test 41c385b7bde3f8e4f4ad98d4f1f737fc6ccc241c2613526fd745eb35430386b2 translated
|
||||
#[test]
|
||||
fn gltf_json_round_trip_preserves_scene_graph() {
|
||||
let original = load_document();
|
||||
let json = original.to_json(None).expect("GltfDocument ToJson");
|
||||
let round_trip = GltfDocument::load_gltf(json, None).expect("GltfDocument LoadGltf");
|
||||
assert_eq!(round_trip.scenes().len(), original.scenes().len());
|
||||
assert_eq!(round_trip.nodes().len(), original.nodes().len());
|
||||
assert_eq!(round_trip.meshes().len(), original.meshes().len());
|
||||
assert_eq!(round_trip.materials().len(), original.materials().len());
|
||||
assert_close(
|
||||
round_trip.materials()[0].base_color_factor().r,
|
||||
original.materials()[0].base_color_factor().r,
|
||||
1e-4,
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.ToGlb_RoundTrip_PreservesGeometry::test 1e97fe2d1492ac195f6a4386329c76ad131ab99a41b8e03216b1bab8b48fae36 translated
|
||||
#[test]
|
||||
fn glb_round_trip_preserves_geometry() {
|
||||
let original = load_document();
|
||||
let glb = original.to_glb().expect("GltfDocument ToGlb");
|
||||
assert_eq!(&glb[..4], &[0x67, 0x6c, 0x54, 0x46]);
|
||||
let round_trip = GltfDocument::load(glb, None).expect("GltfDocument Load");
|
||||
let positions = round_trip
|
||||
.get_positions(first_primitive(&round_trip))
|
||||
.expect("GetPositions");
|
||||
assert_eq!(positions.len(), 3);
|
||||
assert_close(positions[1].x, 1.0, 1e-5);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.Load_AutoDetectsGlbVsJson::test 6d07930be2302e504ef9ece3fef10f47b855d33ae6c8bff152e82df0beb2a474 translated
|
||||
#[test]
|
||||
fn gltf_load_auto_detects_glb_and_json() {
|
||||
let original = load_document();
|
||||
let glb = original.to_glb().expect("GltfDocument ToGlb");
|
||||
let json = original.to_json(None).expect("GltfDocument ToJson");
|
||||
let from_glb = GltfDocument::load(glb, None).expect("load GLB");
|
||||
let from_json = GltfDocument::load(json.into_bytes(), None).expect("load JSON");
|
||||
assert_eq!(from_glb.meshes().len(), 1);
|
||||
assert_eq!(from_json.meshes().len(), 1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.ParseNode_TrsDefaults::test 0f0fbe116d20276c2aee917b940bded9de277ed0b3e3b659844c5b3532755259 translated
|
||||
#[test]
|
||||
fn gltf_node_trs_defaults() {
|
||||
let document = load_document();
|
||||
let node = &document.nodes()[0];
|
||||
assert!(node.matrix().is_none());
|
||||
assert_eq!(
|
||||
vector3_values(&node.translation()),
|
||||
vector3_values(&Vector3::zero())
|
||||
);
|
||||
assert_eq!(
|
||||
quaternion_values(&node.rotation()),
|
||||
quaternion_values(&Quaternion::identity())
|
||||
);
|
||||
assert_eq!(
|
||||
vector3_values(&node.scale()),
|
||||
vector3_values(&Vector3::one())
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.ParseNode_ExplicitMatrix::test 197ba2ee3a66cbb7d927acea13ce9dc84e62af8a500d939957749039118755c8 translated
|
||||
#[test]
|
||||
fn gltf_node_explicit_matrix() {
|
||||
let document = GltfDocument::load_gltf(
|
||||
r#"{
|
||||
"asset": { "version": "2.0" },
|
||||
"nodes": [{
|
||||
"matrix": [1,0,0,0, 0,1,0,0, 0,0,1,0, 5,6,7,1]
|
||||
}]
|
||||
}"#
|
||||
.into(),
|
||||
None,
|
||||
)
|
||||
.expect("GltfDocument LoadGltf");
|
||||
let matrix = document.nodes()[0]
|
||||
.matrix()
|
||||
.flatten()
|
||||
.expect("explicit matrix");
|
||||
assert_close(matrix.m14, 5.0, 1e-5);
|
||||
assert_close(matrix.m24, 6.0, 1e-5);
|
||||
assert_close(matrix.m34, 7.0, 1e-5);
|
||||
}
|
||||
@@ -90,19 +90,6 @@
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.AvatarAppearanceEventArgs_DecodeVisualParams_EmptyList_ReturnsEmptyDictionary::test af99909259d531024895ce7ea325b49927a12daa886a35eab3d52e3f8fc76921
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.AvatarAppearanceEventArgs_DecodeVisualParams_RoundTrip_DefaultValues::test 0aec57fab35764525195e6c0e08a63ff10a467be684295381731c04e836539b5
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.AvatarAppearanceEventArgs_DecodeVisualParams_MatchesAvatarDecodeVisualParams::test ff87dd3a506027ad248006b3b55d85a18b0810bc5b4e3a72eb81d31ebbe4184a
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetBaseColorFactor_OverrideToDefault_IsNudgedOffDefault::test df553fd4df83e48d4dd74cdd8aa15a737ea3a416bcad802f7110bbfe79928a31
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetBaseColorFactor_NotOverride_LeavesExactDefaultUnchanged::test fec94fcfac0f36cc5813ed087a30e04fcc9815bc02072ea3f5dd282b8698a89c
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetMetallicFactor_OverrideToOne_ClampsBelowDefault::test 7fcee795160428082f6e579881867c7b6c83f31549077fc28a46d18c75c485c9
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetAlphaMode_OverrideToDefaultOpaque_SetsOverrideFlag::test 8af09d12a58083657e27e285802bb3a6a1d1c136397cea53865d964006343715
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetTextureId_OverrideToNull_UsesSentinelUuid::test d9ebf410d2a55c3619b99524a571396fb268e5edd41de955cb86e4ec8cc55c78
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ApplyOverride_SentinelTexture_ClearsBaseTexture::test 17fd8cdb12ed5d1d0aa1b0a05dbcc357f75aa350d5079b066c957da459d9f628
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ApplyOverride_UntouchedTexture_LeavesBaseTextureAlone::test 80ec5e369e3682d92ec6996841b15bda38a3ef6edcd36a2fd9893d8c15459348
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ApplyOverride_ChangedScalar_ReplacesBaseValue::test 4c305c54c4e451932fbd4a4719957f92f38a7f7d28259559b43cb95fcf9250d1
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.SetBaseMaterial_ResetsFieldsButKeepsTransforms::test 39312602e736fd8607a41d9e6b6348bfaf6e659cf3f63100ee15edd20b672306
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ToOverrideOsd_RoundTrip_PreservesOverriddenFields::test 8d542528a14e3b4dcb74ea8a940a44673aada51f98baf8abcdd59a06f36e3cb0
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ToOverrideOsd_UntouchedMaterial_ProducesEmptyMap::test c9e29f7ec0e6b28579e0499e3ec89841e01a313a9386ba60257e5e701129b1c2
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ToOverrideOsd_OverrideToDefaultRoughness_StillEncodesField::test 4ea9920c6709bd29858a8da66313fcee5ebebd646743c5d822dd6c9e477bf3b4
|
||||
// pending-parity-case: LibreMetaverse.Tests/AssetMaterialOverrideTests.cs::AssetMaterialOverrideTests.ToJson_RoundTrip_PreservesNameAndColor::test d7ae4270d82671a970fc1b6457292860d24481dd84e9fb919ae60fded5f1914e
|
||||
// pending-parity-case: LibreMetaverse.Tests/AvatarManagerTests.cs::AvatarManagerTests.RequestOwnAvatarTextures_WhenNotConnected_DoesNotThrow::test bf3539f68a0adc58c2166289ca1c75f6ff03906f71ffe2fb749f6990404b541a
|
||||
// pending-parity-case: LibreMetaverse.Tests/AvatarManagerTests.cs::AvatarManagerTests.UpdateLastReceivedCOFVersion_AcceptsHigherVersion::test 3656364491dcd7a05c868b11ea0d8be48609d10c6054b9696f54cbac10cfe6df
|
||||
// pending-parity-case: LibreMetaverse.Tests/AvatarManagerTests.cs::AvatarManagerTests.UpdateLastReceivedCOFVersion_RejectsLowerVersion::test f4a827fcace9d50306a8c375183e056140996d2a39b02e4dd12fc6cc79e5d0f0
|
||||
@@ -133,7 +120,6 @@
|
||||
// pending-parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.ObjectManager_Null_Throws::test 8a11feba0edfb35e5dd99f681182e8f5a5cf8a3f738211b45a683a8a2ad45ddb
|
||||
// pending-parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.AgentManager_Null_Throws::test d86e41b6cdd03063685aa330c31b9a274c1d400b9a461abf3065fe185fe0bbf0
|
||||
// pending-parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.AvatarManager_Null_Throws::test 54f23cbf0ba87b0525c2914e78d75808e93fd1c460fc0bec4d15f09575b1431c
|
||||
// pending-parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.AssetManager_Null_Throws::test 4fa1be8b233dacf6a5955359f2197ff77ae85ffbf2c3c68fcd8cbe672c2c5f91
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.Constructor_WithNullClient_ThrowsArgumentNullException::test 243079029ec81f92ffbc587007a2421389963f72c7843786c5b9a8634a7ddca3
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.Dispose_CalledOnce_DoesNotThrow::test 1d0daac0bfa091bc3c3bffddc32a1511295dd7101f8ab5dfbf305b13b9ac7405
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.Dispose_CalledMultipleTimes_DoesNotThrow::test 124b41c342a295f02e9d5991d1dead0ff3e9a780f96424b88f75117ca206460b
|
||||
@@ -194,28 +180,6 @@
|
||||
// pending-parity-case: LibreMetaverse.Tests/ExperiencePreferencesMessageTests.cs::ExperiencePreferencesMessageTests.ExtractExperiencePermission_Allowed_ReturnsAllow::test cf095ab428713004ebac6e1915a47ae0c03bd2958addbba2a39fd2f0edf51a74
|
||||
// pending-parity-case: LibreMetaverse.Tests/ExperiencePreferencesMessageTests.cs::ExperiencePreferencesMessageTests.ExtractExperiencePermission_Blocked_ReturnsBlock::test af084d1ab7a11079e6251865e8fd5aecfde38d2df359ebc1e208bc74925935c0
|
||||
// pending-parity-case: LibreMetaverse.Tests/ExperiencePreferencesMessageTests.cs::ExperiencePreferencesMessageTests.ExtractExperiencePermission_NeitherList_ReturnsForget::test 93204469ecfec2f3f4eb6838c99f6e2baf09bf76a075958d1ed369ba03767158
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.SetMaterialOverrideAsync_HappyPath_PostsBareArrayWithGltfJson::test 0c51b7b793111f5433e52057f26fa5a98d983e7230fefeb61a7b3408e97f28ee
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.ClearMaterialOverrideAsync_SendsEmptyGltfJson::test 8394d063ea71447d9ce2b76fd00be1d10967f9193e1eb909c5b9f2da56eec812
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.ApplyMaterialAsync_WithoutOverride_SendsAssetIdOnly::test 1db03ab6710ecf532644398d1fef5e82520e1206058d66fb15c8885fdc8f8363
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.SendMaterialUpdatesAsync_MultipleEntries_SendsSingleArrayBody::test 621dca88e7f1c9e024563204ca05c3c8d9a03c4b5a7b31ec1c006abe6732b47b
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.SendMaterialUpdatesAsync_ServerRejects_ReturnsFalse::test e9fbd95fff84695e2cb1a35943bda768f00cf9015b25e0ae1505dce4dde603a4
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialOverrideCapTests.cs::GLTFMaterialOverrideCapTests.SendMaterialUpdatesAsync_NoCapability_ReturnsFalseWithoutRequest::test fdceb6bf865cb23386a6b82a9741f230e5c22b0ec6d37bc2ac8478f29292a49f
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialUploadTests.cs::GLTFMaterialUploadTests.RequestUpdateMaterialAgentInventoryAsync_HappyPath_PostsMetadataThenJsonAndReturnsNewAsset::test 5ac0e3c27fa6ebfddc9d7582aefb0684a676413948b055382c43b1b0b1cd7e7e
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialUploadTests.cs::GLTFMaterialUploadTests.RequestUpdateMaterialTaskInventoryAsync_HappyPath_PostsItemIdAndTaskId::test 7ac0e7d210b1aefa795e479f4da0d2dd4caae0b3bbe84ca124707c3ae005bbbd
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialUploadTests.cs::GLTFMaterialUploadTests.RequestUpdateMaterialAgentInventoryAsync_NoCapability_Throws::test 325269807d778264e571d1518ca9a2ca69a27ba67ad689e580f2636ab595f335
|
||||
// pending-parity-case: LibreMetaverse.Tests/GLTFMaterialUploadTests.cs::GLTFMaterialUploadTests.RequestUpdateMaterialAgentInventoryAsync_UploadedJsonRoundTripsMaterial::test fd059dfc8c9299c3b6583b3b47ba18ae9c92e3ad923f88634019b0ab9f34d401
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.LoadGltf_ParsesSceneGraph::test e20583d8de31f793d1dc49d1dfde89e1eb8c00186359e7df4184e862ec9ed649
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.LoadGltf_ParsesMeshAndPrimitive::test ef6a76308db1966423c7746f5414f3d0553587efc388bbedb962f38cc122ecaf
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.LoadGltf_ParsesMaterial::test 0147b4d7102c5223f247f69fa4cf3daeb0aa6300ad46ef34d6a17163b694c13e
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.GetPositions_ReturnsCorrectTriangle::test c3d444122ab73794a011d5a5aafb0c2aa030975393f967e871dc88db200f5e96
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.GetIndices_ReturnsCorrectValues::test fa39e87a3dfee7258d9a95907a97cbb107f5add7d6a6f9d9800249bb67e2fc58
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.GetPositions_EmptyWhenNoAttribute::test 06c691911ee6933f1884f6540d69afafa1f272acfed827c628580438204d9b4b
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.GetNormals_EmptyWhenNoAttribute::test e04480b0b9e23cb561cc55e744ebd85203c759f98ad69febeeb291919f0d91af
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.ToJson_RoundTrip_PreservesSceneGraph::test 41c385b7bde3f8e4f4ad98d4f1f737fc6ccc241c2613526fd745eb35430386b2
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.ToGlb_RoundTrip_PreservesGeometry::test 1e97fe2d1492ac195f6a4386329c76ad131ab99a41b8e03216b1bab8b48fae36
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.Load_AutoDetectsGlbVsJson::test 6d07930be2302e504ef9ece3fef10f47b855d33ae6c8bff152e82df0beb2a474
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.ParseNode_TrsDefaults::test 0f0fbe116d20276c2aee917b940bded9de277ed0b3e3b659844c5b3532755259
|
||||
// pending-parity-case: LibreMetaverse.Tests/GltfDocumentTests.cs::GltfDocumentTests.ParseNode_ExplicitMatrix::test 197ba2ee3a66cbb7d927acea13ce9dc84e62af8a500d939957749039118755c8
|
||||
// pending-parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseLinksFromEmbedded_ObjectAsset_ResultsInAttachmentInventoryTypeAndParsesFields::test 3ae365ed34f12d036dcd44c94f8568d163cfeec2a58b4975975b77b418770131
|
||||
// pending-parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseItemsFromEmbedded_ItemsKey_ParsesConcreteItems::test d9e7c64106639071e1ec6ada7346bfa050a31183becaac79efefcd4755fe2855
|
||||
// pending-parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseLinksFromEmbedded_MeshAsset_TreatedAsAttachment::test f807110d577c654128dd8d42e618c610c260c4f3367cf2795776564409f876a2
|
||||
@@ -339,10 +303,6 @@
|
||||
// pending-parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_Indexer_ReturnsAttachment_WhenTargetIsAttachment::test f58debff8f66b7b417215eb6879f96935647b66cc619fdb00e6815c9ce5e7c67
|
||||
// pending-parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_Indexer_ReturnsObject_WhenTargetIsObject::test b8137c994019103977b0b85d8c148e12ae8f9051334ca487db7c88bcbe707d40
|
||||
// pending-parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_NotContains_WhenTargetAbsent::test 6900e220c33ec135d02c55e047c7052a095d5dd9d71da4a857ae70bc151c472b
|
||||
// pending-parity-case: LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_StandardRegion_Loads256x256::test c4e3a994baf06b0106a6614e9c3efbcc27e45ff1725f5470d2db6ded1fff6014
|
||||
// pending-parity-case: LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_Varregion_Loads512x512::test 4820338f10acbb4987e26992d7a7957be58ab6bc548674bf18943ef312962894
|
||||
// pending-parity-case: LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_WrongByteCount_FailsGracefully::test ff6fb4feb2773c93397d412d0ecf6aef1f3636e823dabb729a7a6cbe94d1513f
|
||||
// pending-parity-case: LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_NonSquarePostCount_FailsGracefully::test 218754e53232cd10318668c70b94ae9d7d541d09598b0490082e023e76d6045f
|
||||
// pending-parity-case: LibreMetaverse.Tests/OfflineMessagesTests.cs::OfflineMessagesTests.RetrieveInstantMessagesAsync_BareArrayOfArraysResponse_RaisesInstantMessage::test d51f69e0fa1e1e59a5cedec7d60315d1f590848672a9f4f0c5e21d2abff5c372
|
||||
// pending-parity-case: LibreMetaverse.Tests/OfflineMessagesTests.cs::OfflineMessagesTests.RetrieveInstantMessagesAsync_MessagesMapResponse_RaisesInstantMessage::test dbce6320d57d12ca5557cfba65257e15be314cde947b20dd21bc386819fcb3ce
|
||||
// pending-parity-case: LibreMetaverse.Tests/PrimObjectTests.cs::PrimObjectTests.PathBegin::test 5c8e14e1d08a91a4e7c3e252c932b8fe15cf6b5231cc9fe5bb7ef2ae6e2c8299
|
||||
@@ -996,10 +956,6 @@
|
||||
// pending-parity-case: LibreMetaverse.Tests/RequestTaskInventoryCapTests.cs::RequestTaskInventoryCapTests.GetTaskInventoryAsync_PlainAssetId_ParsesWithoutDecryption::test 95f39928dae61bca86b7d0a0702307db6c5fdc754e51f73a24bd5ee131e6de3f
|
||||
// pending-parity-case: LibreMetaverse.Tests/RequestTaskInventoryCapTests.cs::RequestTaskInventoryCapTests.GetTaskInventoryAsync_NonSuccessStatus_ReturnsContentsFolderOnly::test b8a25891064e470ac8d77ecd8a4847cf773b043de5ebeae275a9dd6669518585
|
||||
// pending-parity-case: LibreMetaverse.Tests/RequestTaskInventoryCapTests.cs::RequestTaskInventoryCapTests.GetTaskInventoryAsync_NoCapability_DoesNotMakeHttpRequest::test c0c43ebcf781fb81b1fef7ce1dd2774e350d92ef882f49876f1a16d23a338592
|
||||
// pending-parity-case: LibreMetaverse.Tests/SendPostcardTests.cs::SendPostcardTests.SendPostcardAsync_HappyPath_PostsMetadataThenImageAndReturnsTrue::test 2e02bd16ef1431c2ca82d7804dffc764be0175cff5daff8c38d0a61641439e06
|
||||
// pending-parity-case: LibreMetaverse.Tests/SendPostcardTests.cs::SendPostcardTests.SendPostcardAsync_UploaderMissingFromResponse_ReturnsFalseWithoutSecondRequest::test 2f9498d57d7a512399f9b108765e6e8da8e4c937402f9671d580c66332630432
|
||||
// pending-parity-case: LibreMetaverse.Tests/SendPostcardTests.cs::SendPostcardTests.SendPostcardAsync_UploadDoesNotComplete_ReturnsFalse::test 937b682b406506ec9fba9570852bbf8689450a11cbecb85979af97609b1794f9
|
||||
// pending-parity-case: LibreMetaverse.Tests/SendPostcardTests.cs::SendPostcardTests.SendPostcardAsync_NoCapability_ReturnsFalseWithoutRequest::test 8d3ef84e873096d9388bb7db3eaeeb79c661fd9951e338f71bbf3251ae6580e8
|
||||
// pending-parity-case: LibreMetaverse.Tests/SimConsoleTests.cs::SimConsoleTests.SendSimConsoleCommandAsync_IgnoresPostBody_UsesSimConsoleResponseEvent::test df6eb48241f71c34074be66869c9ae1d5980186583259568728261b5eedd7c48
|
||||
// pending-parity-case: LibreMetaverse.Tests/SimConsoleTests.cs::SimConsoleTests.SendSimConsoleCommandAsync_NoResponseEvent_ReturnsNullAfterTimeout::test 2ac5a6c96f3acec341056387d727288fd3661565bd2a7c385078602efe8661da
|
||||
// pending-parity-case: LibreMetaverse.Tests/SimConsoleTests.cs::SimConsoleTests.SimConsoleResponseMessage_Deserialize_ReadsBodyField::test 4d367bc3fd012d1579847fd9837bf883c5ea95452776a086bbf856899d7c2099
|
||||
@@ -1038,12 +994,6 @@
|
||||
// pending-parity-case: LibreMetaverse.Tests/SlurlParserTests.cs::SlurlParserTests.ParseAllSlappCommands_RecognizesCorrectly::test abf53480da20d1ff57f5f06f1433c120ea84e0d6d5363cb33e4a275d76cfa306
|
||||
// pending-parity-case: LibreMetaverse.Tests/StartAuctionTests.cs::StartAuctionTests.ViewerStartAuctionPacket_RoundTripsAgentAndParcelFields::test f37ef06cfba37754effe04a0bb0edfa159c761b811a05efd95157896756bef16
|
||||
// pending-parity-case: LibreMetaverse.Tests/StartAuctionTests.cs::StartAuctionTests.StartAuction_DoesNotThrow::test deec194333b480dabb3f6e6d96b360a29d11a40ca1103117fc7ce5cdb80d6eb0
|
||||
// pending-parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.GetTerrainMaterialOverridesAsync_ParsesFourSlotsWithSomeEmpty::test 0b7f2b5a7a95c70f4ed97b9b028f3ec16f1cd427a9d4d1b133523bd331f6b9f2
|
||||
// pending-parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.GetTerrainMaterialOverridesAsync_ServerReportsFailure_ReturnsNull::test c66b84662333288b7328822d1f9fa79450075d44a1178a9b0b661671072efe5b
|
||||
// pending-parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.GetTerrainMaterialOverridesAsync_NoCapability_ReturnsNullWithoutRequest::test 677f80689e1b6a67893d100e1116805fb9f63c5b6ec33e64a4dc9a4cf24c1237
|
||||
// pending-parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.SetTerrainMaterialOverridesAsync_MixOfNullAndSet_PostsFourEntries::test a4ce031e565ca7eb1864064d299dbf0c7b715581ce330a57be9c3aa93987e67c
|
||||
// pending-parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.SetTerrainMaterialOverridesAsync_WrongLength_Throws::test 836099a369b37555049b1c1ddfb9562c57cdef88381b7a79e8b80fe62b169a44
|
||||
// pending-parity-case: LibreMetaverse.Tests/TerrainMaterialOverrideTests.cs::TerrainMaterialOverrideTests.SetTerrainMaterialOverridesAsync_NoCapability_ReturnsFalseWithoutRequest::test 37948cbc0240910d63782d88c0fb9f1d239215cea34a5aa84ac68a10d0555e87
|
||||
// pending-parity-case: LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_HighFace_TextureID_IsPreserved::case:d3ad6116f2458248 5f215cd1c50fa8871967653b4667f848c14ff24a3b71906e51aac13c56de1f55
|
||||
// pending-parity-case: LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_HighFace_TextureID_IsPreserved::case:c6f3ac57944a5314 5f215cd1c50fa8871967653b4667f848c14ff24a3b71906e51aac13c56de1f55
|
||||
// pending-parity-case: LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_HighFace_TextureID_IsPreserved::case:d59eced1ded07f84 5f215cd1c50fa8871967653b4667f848c14ff24a3b71906e51aac13c56de1f55
|
||||
@@ -1054,12 +1004,6 @@
|
||||
// pending-parity-case: LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_Face32_RepeatU_IsPreserved::test 58e80815263025ec54cd15e3c9a42771f5e55c81e9acb212a0f163faef9fd499
|
||||
// pending-parity-case: LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_Face32_RepeatV_IsPreserved::test fbeb1fdd584a26576b6f1ba653b2995d1a6d6bccc2c1dc51e46aa9f211b78724
|
||||
// pending-parity-case: LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_AllFaces_TextureIDs_AllPreserved::test 5e5a390af8deff77ef80f751735456541f24d7e27666557d50d99065cc3ba6a4
|
||||
// pending-parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_AgentInventoryItem_SendsBareItemIdAndReturnsNewAsset::test 40ca874a37dade3bfbb391a2b4a75c684cfd7509b269286ccc14d747340d095d
|
||||
// pending-parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_TaskInventoryItem_SendsItemIdAndTaskId::test dae80f9a7ba6222a651165f779c123d8472f88a17490e69a1112acc3cec6d108
|
||||
// pending-parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_KnownLocalFolder_SendsCategoryId::test 1ccca44bbead54fd5041c41fc6560478ba17f9e5d9bacff21096b254d2f526db
|
||||
// pending-parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_NoCapability_ReturnsNullWithoutRequest::test 2bc1ad18b159c5d62a18d2208ed3cf3c88d3f666a0e0dad8730778cd22b59eda
|
||||
// pending-parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_MetadataResponseMissingUploader_ReturnsNullWithoutSecondRequest::test 8db3eddf1204ad795e9d5ef15365f422f96191a8b4c24ef3393b03c10d92d662
|
||||
// pending-parity-case: LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_UploadDoesNotComplete_ReturnsNull::test e870f6913e3f45676ce490069930427e6c625072fc1d6ebbf16f503be51df4ae
|
||||
// pending-parity-case: LibreMetaverse.Rendering.Tests/Avatar/AvatarBoneMathTests.cs::AvatarBoneMathTests.BuildBoneWorldMatrices_UnitScale_MatchesNaiveMatrixChain::test 32ea442e98ebfe42238424274aefa960d9bac9a5048c4c971b315b712f870291
|
||||
// pending-parity-case: LibreMetaverse.Rendering.Tests/Avatar/AvatarBoneMathTests.cs::AvatarBoneMathTests.BuildBoneWorldMatrices_AnisotropicParentScale_OffsetsChildPositionButNotChildScale::test c82d9c6df0612703729e75ec955e4ef90651bb290d3daebe8d8bed7bba8891a3
|
||||
// pending-parity-case: LibreMetaverse.Rendering.Tests/MeshFoundry/MeshFoundryTests.cs::MeshFoundryTests.GenerateSimpleMesh_Box_ReturnsNonNull::test cc5f4d8a21dd21e23e21c6372a4b21e100bffb0fc2a6b9a745d4283c1b05286d
|
||||
|
||||
Reference in New Issue
Block a user