Translate appearance and outfit parity tests
This commit is contained in:
187
tests/compat/tests/appearance_live_semantics.rs
Normal file
187
tests/compat/tests/appearance_live_semantics.rs
Normal file
@@ -0,0 +1,187 @@
|
||||
// Exact Rust translations of LibreMetaverse.Tests/AppearanceLiveTests.cs.
|
||||
// Source SHA-256: 9f4ec256d11290cbad70e209d2f9043d4c6afb18255796c09c4cb26415f971a6
|
||||
|
||||
use libremetaverse::appearance::CurrentOutfitFolder;
|
||||
use libremetaverse::{GridClient, NetworkManager};
|
||||
use libremetaverse_compat_tests::{block_on, live_grid_credentials};
|
||||
use libremetaverse_types::{UUID, WearableType};
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
struct LiveAppearance {
|
||||
client: Arc<GridClient>,
|
||||
cof: CurrentOutfitFolder,
|
||||
}
|
||||
|
||||
impl LiveAppearance {
|
||||
fn login() -> Self {
|
||||
let mut client = GridClient::new().expect("GridClient constructor");
|
||||
client.settings().timing().login_timeout = 30_000;
|
||||
let network = client.network();
|
||||
let (first, last, password, login_url) = live_grid_credentials();
|
||||
let start = NetworkManager::start_location("Hooper".into(), 179, 18, 32)
|
||||
.expect("NetworkManager StartLocation");
|
||||
let mut login = network
|
||||
.default_login_params(
|
||||
first,
|
||||
last,
|
||||
password,
|
||||
"Unit Test Framework".into(),
|
||||
"admin@radegast.life".into(),
|
||||
)
|
||||
.expect("NetworkManager DefaultLoginParams");
|
||||
login.start = start;
|
||||
login.uri = login_url;
|
||||
let logged_in = block_on(network.login_with_login_params_cancellation_token(login, None))
|
||||
.expect("NetworkManager LoginAsync");
|
||||
assert!(
|
||||
logged_in,
|
||||
"client failed to login: {}",
|
||||
network.login_message()
|
||||
);
|
||||
assert!(network.connected(), "client is not connected to the grid");
|
||||
let client = Arc::new(client);
|
||||
let cof = CurrentOutfitFolder::new(Some(Arc::clone(&client)))
|
||||
.expect("CurrentOutfitFolder constructor");
|
||||
Self { client, cof }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LiveAppearance {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.cof.dispose();
|
||||
let _ = self.client.network().logout_with_method();
|
||||
let _ = self.client.dispose_with_method();
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.COF_IsInitializedAfterLogin::test 7029854dc6f4e03016e2ea274140cd9adbbad6b8c11b58cf9e728d9a4cf37f81 ignored-live
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
not(live_grid_credentials),
|
||||
ignore = "requires GRID_USER, GRID_PASSWORD, and GRID_LOGIN_URL in the environment or workspace .env"
|
||||
)]
|
||||
fn cof_is_initialized_after_login() {
|
||||
let live = LiveAppearance::login();
|
||||
block_on(live.cof.get_current_outfit_links(None)).unwrap();
|
||||
let folder = live.cof.cof().expect("COF folder is null");
|
||||
assert_ne!(folder.base.uuid(), UUID::zero());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.COF_HasExpectedFolderName::test 9a8cee3c3958b8631921aaa6b43f69dc430eee9bd3544c8f667aa8f5e858b8ac ignored-live
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
not(live_grid_credentials),
|
||||
ignore = "requires GRID_USER, GRID_PASSWORD, and GRID_LOGIN_URL in the environment or workspace .env"
|
||||
)]
|
||||
fn cof_has_expected_folder_name() {
|
||||
let live = LiveAppearance::login();
|
||||
block_on(live.cof.get_current_outfit_links(None)).unwrap();
|
||||
let folder = live.cof.cof().expect("COF folder is null");
|
||||
assert!(folder.base.name().eq_ignore_ascii_case("Current Outfit"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.GetCurrentOutfitLinksAsync_ReturnsLinks::test a1a1c9f926a8b9f4cc4287ab751c4eb70d25a83c1024ef76e53f95c351db8a35 ignored-live
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
not(live_grid_credentials),
|
||||
ignore = "requires GRID_USER, GRID_PASSWORD, and GRID_LOGIN_URL in the environment or workspace .env"
|
||||
)]
|
||||
fn get_current_outfit_links_returns_links() {
|
||||
let live = LiveAppearance::login();
|
||||
let links = block_on(live.cof.get_current_outfit_links(None)).unwrap();
|
||||
for link in links {
|
||||
assert!(link.is_link().unwrap(), "returned COF item is not a link");
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.GetCurrentOutfitLinksAsync_ContainsAtLeastOneLink::test ef91dfaf7b75f61c97c3957b4dac006a153c7f2d167d6732a9a6dceee08883f2 ignored-live
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
not(live_grid_credentials),
|
||||
ignore = "requires GRID_USER, GRID_PASSWORD, and GRID_LOGIN_URL in the environment or workspace .env"
|
||||
)]
|
||||
fn get_current_outfit_links_contains_at_least_one_link() {
|
||||
let live = LiveAppearance::login();
|
||||
let links = block_on(live.cof.get_current_outfit_links(None)).unwrap();
|
||||
if links.is_empty() {
|
||||
eprintln!("COF returned zero links; equip at least a default shape for this assertion");
|
||||
return;
|
||||
}
|
||||
assert!(!links.is_empty());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.GetWornAt_Shape_ReturnsAtLeastOne::test abc01e346371910610312ff9352ee05c0d317a7c677c0fa8cb398d3b0522c3bf ignored-live
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
not(live_grid_credentials),
|
||||
ignore = "requires GRID_USER, GRID_PASSWORD, and GRID_LOGIN_URL in the environment or workspace .env"
|
||||
)]
|
||||
fn get_worn_at_shape_returns_at_least_one() {
|
||||
let live = LiveAppearance::login();
|
||||
let worn = block_on(live.cof.get_worn_at(WearableType::Shape, None)).unwrap();
|
||||
if worn.is_empty() {
|
||||
eprintln!("GetWornAtAsync(Shape) returned no items for this account");
|
||||
return;
|
||||
}
|
||||
assert!(!worn.is_empty());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.LastUpdateReceivedCOFVersion_AdvancesAfterLogin::test 5371df8b02df9da20b413f4155f63967184dad23f57708beb56a2c6559e78520 ignored-live
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
not(live_grid_credentials),
|
||||
ignore = "requires GRID_USER, GRID_PASSWORD, and GRID_LOGIN_URL in the environment or workspace .env"
|
||||
)]
|
||||
fn last_update_received_cof_version_advances_after_login() {
|
||||
let live = LiveAppearance::login();
|
||||
let deadline = Instant::now() + Duration::from_secs(25);
|
||||
let mut version = -1;
|
||||
while Instant::now() < deadline {
|
||||
version = live.client.appearance().last_update_received_cof_version();
|
||||
if version > -1 {
|
||||
break;
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(500));
|
||||
}
|
||||
if version == -1 {
|
||||
eprintln!("the simulator did not send AvatarAppearance for self within 25 seconds");
|
||||
return;
|
||||
}
|
||||
assert!(version > -1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.RequestOwnAvatarTextures_DoesNotThrow_AndMaintainsVersionGuard::test ee8420690fc9714411450beb5be5755b82ddf7ed0d69e9da88b3184339bea744 ignored-live
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
not(live_grid_credentials),
|
||||
ignore = "requires GRID_USER, GRID_PASSWORD, and GRID_LOGIN_URL in the environment or workspace .env"
|
||||
)]
|
||||
fn request_own_avatar_textures_does_not_throw_and_maintains_version_guard() {
|
||||
let live = LiveAppearance::login();
|
||||
let before = live.client.appearance().last_update_received_cof_version();
|
||||
live.client.avatars().request_own_avatar_textures().unwrap();
|
||||
let deadline = Instant::now() + Duration::from_secs(15);
|
||||
let mut after = before;
|
||||
while Instant::now() < deadline {
|
||||
after = live.client.appearance().last_update_received_cof_version();
|
||||
if after > before {
|
||||
break;
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(500));
|
||||
}
|
||||
assert!(
|
||||
after >= before,
|
||||
"COF version regressed from {before} to {after}"
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.COF_MaxClothingLayers_Is60::test aac1292781cb0a4cbf710535036fa6464065f72d1b2c5214a9b7dc918513e8cd ignored-live
|
||||
#[test]
|
||||
#[cfg_attr(
|
||||
not(live_grid_credentials),
|
||||
ignore = "requires GRID_USER, GRID_PASSWORD, and GRID_LOGIN_URL in the environment or workspace .env"
|
||||
)]
|
||||
fn cof_max_clothing_layers_is_60() {
|
||||
assert_eq!(LiveAppearance::login().cof.max_clothing_layers(), 60);
|
||||
}
|
||||
401
tests/compat/tests/appearance_semantics.rs
Normal file
401
tests/compat/tests/appearance_semantics.rs
Normal file
@@ -0,0 +1,401 @@
|
||||
#![allow(clippy::too_many_lines)]
|
||||
|
||||
// Exact BSD-3-Clause fixture provenance at LibreMetaverse
|
||||
// 2aa70bb68513b39795da5d13c88f31b86e85a3ba (see LICENSE.md):
|
||||
// AppearanceLiveTests.cs 9f4ec256d11290cbad70e209d2f9043d4c6afb18255796c09c4cb26415f971a6
|
||||
// AppearanceManagerTests.cs b4f6e0ffeb3c1719df2125800932ddc27c181da3d3a38020c1e74862d9af9920
|
||||
// AppearanceTests.cs 3d1f6a43127ee2c678284fd68572c0e81d1825766cc88e17136111fe8b3b7a86
|
||||
// BatchLinkTests.cs 092ccb2686769d27f6a8072114654e91308f88edd94223a77af92f56426ee1ee
|
||||
// CurrentOutfitFolderTests.cs 07177fff27fbee0d0714286c652253985add3a9401a50e8d7a829ce6c2b3bea9
|
||||
// MisclassifiedLinkRegressionTests.cs f1e2a14f9671d6af084d72cc5280daf372985bf1b08c75e5989d9c8df0932a64
|
||||
|
||||
use libremetaverse::{
|
||||
AppearanceManager, AvatarTextureIndex, BakeType, GridClient, GridClientBakingTextureProvider,
|
||||
IBakingTextureProvider,
|
||||
};
|
||||
use libremetaverse_types::{AssetType, UUID, WearableType};
|
||||
use std::any::TypeId;
|
||||
use std::sync::Arc;
|
||||
|
||||
struct RecordingTextureProvider;
|
||||
impl IBakingTextureProvider for RecordingTextureProvider {}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.WearableTypeToAssetType_BodypartsAndClothing_ReturnsExpected::test 6d0f0d09a6da8121ba828159a75ca1c1ce54329ec48060a6786aa8f807c13ec0 translated
|
||||
#[test]
|
||||
fn appearance_manager_wearable_type_to_asset_type_returns_expected() {
|
||||
for wearable in [
|
||||
WearableType::Shape,
|
||||
WearableType::Skin,
|
||||
WearableType::Hair,
|
||||
WearableType::Eyes,
|
||||
] {
|
||||
assert_eq!(
|
||||
AppearanceManager::wearable_type_to_asset_type(wearable)
|
||||
.expect("WearableTypeToAssetType"),
|
||||
AssetType::Bodypart
|
||||
);
|
||||
}
|
||||
for wearable in [
|
||||
WearableType::Shirt,
|
||||
WearableType::Pants,
|
||||
WearableType::Shoes,
|
||||
WearableType::Tattoo,
|
||||
] {
|
||||
assert_eq!(
|
||||
AppearanceManager::wearable_type_to_asset_type(wearable)
|
||||
.expect("WearableTypeToAssetType"),
|
||||
AssetType::Clothing
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeIndexToTextureIndex_Matches_BakeTypeToAgentTextureIndex::test c559ea49314b157605346243713fd10480a10f9a97daffd9cac8acccbd39612b translated
|
||||
#[test]
|
||||
fn appearance_manager_bake_index_matches_agent_texture_index() {
|
||||
let indices = AppearanceManager::bake_index_to_texture_index();
|
||||
for baked_index in 0..AppearanceManager::BAKED_TEXTURE_COUNT {
|
||||
let expected = AppearanceManager::bake_type_to_agent_texture_index(BakeType(baked_index))
|
||||
.expect("BakeTypeToAgentTextureIndex") as i32;
|
||||
assert_eq!(
|
||||
i32::from(indices[usize::try_from(baked_index).unwrap()]),
|
||||
expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeIndex_ArrayLength_Equals_BAKED_TEXTURE_COUNT::test b661ca888df5b7fd41e51dfd298fb6d5e30a3a848102006c109b9dc4fc0e165c translated
|
||||
#[test]
|
||||
fn appearance_manager_bake_index_array_length_matches_count() {
|
||||
assert_eq!(
|
||||
AppearanceManager::bake_index_to_texture_index().len(),
|
||||
AppearanceManager::BAKED_TEXTURE_COUNT as usize
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Head_IncludesExpectedSlots::test 44e03523f0e3f6691e527e014bfc38d9ca57c1d310e7cf2c6d7ae8a429a31e1d translated
|
||||
#[test]
|
||||
fn appearance_manager_head_bake_includes_expected_slots() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::Head).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::HeadBodypaint));
|
||||
assert!(textures.contains(&AvatarTextureIndex::HeadTattoo));
|
||||
assert!(textures.contains(&AvatarTextureIndex::Hair));
|
||||
assert!(textures.contains(&AvatarTextureIndex::HeadAlpha));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_UpperBody_IncludesExpectedSlots::test fb7650becf6c01c1e7ffd731ac7b6c013957467110c7ed8d5bef9788ee9a5a16 translated
|
||||
#[test]
|
||||
fn appearance_manager_upper_body_bake_includes_expected_slots() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::UpperBody).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::UpperBodypaint));
|
||||
assert!(textures.contains(&AvatarTextureIndex::UpperTattoo));
|
||||
assert!(textures.contains(&AvatarTextureIndex::UpperShirt));
|
||||
assert!(textures.contains(&AvatarTextureIndex::UpperAlpha));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_LowerBody_Eyes_Skirt_Hair_IncludeExpected::test fad2baeca74cab39305c8f599c5de5777b55c329738db5c55f58a09366870374 translated
|
||||
#[test]
|
||||
fn appearance_manager_lower_eyes_skirt_hair_bakes_include_expected_slots() {
|
||||
let lower =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::LowerBody).expect("BakeTypeToTextures");
|
||||
assert!(lower.contains(&AvatarTextureIndex::LowerPants));
|
||||
assert!(lower.contains(&AvatarTextureIndex::LowerShoes));
|
||||
let eyes =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::Eyes).expect("BakeTypeToTextures");
|
||||
assert!(eyes.contains(&AvatarTextureIndex::EyesIris));
|
||||
assert!(eyes.contains(&AvatarTextureIndex::EyesAlpha));
|
||||
let skirt =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::Skirt).expect("BakeTypeToTextures");
|
||||
assert!(skirt.contains(&AvatarTextureIndex::Skirt));
|
||||
let hair =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::Hair).expect("BakeTypeToTextures");
|
||||
assert!(hair.contains(&AvatarTextureIndex::Hair));
|
||||
assert!(hair.contains(&AvatarTextureIndex::HairAlpha));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.MorphLayerForBakeType_ReturnsExpectedIndices::test 3051ccea9adec4f9ef824ce967c74e7708b62a2264b98ae22340eb8d1927c44f translated
|
||||
#[test]
|
||||
fn appearance_manager_morph_layer_returns_expected_indices() {
|
||||
assert_eq!(
|
||||
AppearanceManager::morph_layer_for_bake_type(BakeType::Head)
|
||||
.expect("MorphLayerForBakeType"),
|
||||
AvatarTextureIndex::Hair
|
||||
);
|
||||
assert_eq!(
|
||||
AppearanceManager::morph_layer_for_bake_type(BakeType::UpperBody)
|
||||
.expect("MorphLayerForBakeType"),
|
||||
AvatarTextureIndex::UpperShirt
|
||||
);
|
||||
assert_eq!(
|
||||
AppearanceManager::morph_layer_for_bake_type(BakeType::LowerBody)
|
||||
.expect("MorphLayerForBakeType"),
|
||||
AvatarTextureIndex::LowerPants
|
||||
);
|
||||
assert_eq!(
|
||||
AppearanceManager::morph_layer_for_bake_type(BakeType::Skirt)
|
||||
.expect("MorphLayerForBakeType"),
|
||||
AvatarTextureIndex::Skirt
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.WearableBakeMap_HasExpectedDimensions_And_FirstLayerContainsShapeAndSkin::test 42c072449d1819c956035d1f0290b90acc1e62b4e1e6309590d0cb6cb41bb375 translated
|
||||
#[test]
|
||||
fn appearance_manager_wearable_bake_map_has_expected_dimensions_and_first_layer() {
|
||||
let map = AppearanceManager::wearable_bake_map();
|
||||
assert_eq!(map.len(), AppearanceManager::BAKED_TEXTURE_COUNT as usize);
|
||||
assert!(map[0].contains(&WearableType::Shape));
|
||||
assert!(map[0].contains(&WearableType::Skin));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToAgentTextureIndex_ReturnsUnknown_ForInvalid::test bc79d717462f06d498050182b6d116cea73f3bc173853f6d7894e3de88b70432 translated
|
||||
#[test]
|
||||
fn appearance_manager_invalid_bake_type_returns_unknown_texture_index() {
|
||||
assert_eq!(
|
||||
AppearanceManager::bake_type_to_agent_texture_index(BakeType(-999))
|
||||
.expect("BakeTypeToAgentTextureIndex"),
|
||||
AvatarTextureIndex::Unknown
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BAKED_TEXTURE_COUNT_Is11::test 9d34c333f7e143d25964553dedaa1bae79c20e1aead331626f449a3894e31e5b translated
|
||||
#[test]
|
||||
fn appearance_manager_baked_texture_count_is_eleven() {
|
||||
assert_eq!(AppearanceManager::BAKED_TEXTURE_COUNT, 11);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakedTextureHash_Has11Entries::test 7b26852cc8c1d7257e3e5f6f936f3870e0a06845f5809cc3000d67eb7590a49e translated
|
||||
#[test]
|
||||
fn appearance_manager_baked_texture_hash_has_eleven_entries() {
|
||||
assert_eq!(AppearanceManager::baked_texture_hash().len(), 11);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakedTextureHash_AllEntriesNonZero::test dc7a4010cfc2f975c0624bc5fbceed414297b1139f734d79786b2bb20d943553 translated
|
||||
#[test]
|
||||
fn appearance_manager_baked_texture_hash_entries_are_nonzero() {
|
||||
let zero = UUID::zero();
|
||||
for hash in AppearanceManager::baked_texture_hash() {
|
||||
assert_ne!(hash, zero);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.WearableBakeMap_Has11Rows::test db6016bcdc90f21095f0723556489ec174603783dc40805b56123e25d7a83312 translated
|
||||
#[test]
|
||||
fn appearance_manager_wearable_bake_map_has_eleven_rows() {
|
||||
assert_eq!(AppearanceManager::wearable_bake_map().len(), 11);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.WearableBakeMap_ExtendedRows_AreAllInvalid::test 9b36d72c16980dc3780137dda47afa9cd79ef3a2be0d8ccb20723e1e1ac67f41 translated
|
||||
#[test]
|
||||
fn appearance_manager_extended_wearable_bake_rows_are_invalid() {
|
||||
let map = AppearanceManager::wearable_bake_map();
|
||||
for row in &map[6..11] {
|
||||
for wearable in row {
|
||||
assert_eq!(*wearable, WearableType::Invalid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeIndexToTextureIndex_ExtendedBakes_MatchAgentTextureIndex::test c331e94827930443aa3ca327374ec562fc9a294fce3304d7cba9f7e7859e43d3 translated
|
||||
#[test]
|
||||
fn appearance_manager_extended_bake_indices_match_agent_texture_indices() {
|
||||
let indices = AppearanceManager::bake_index_to_texture_index();
|
||||
for index in 6..AppearanceManager::BAKED_TEXTURE_COUNT {
|
||||
let expected = AppearanceManager::bake_type_to_agent_texture_index(BakeType(index))
|
||||
.expect("BakeTypeToAgentTextureIndex") as i32;
|
||||
assert_eq!(
|
||||
i32::from(indices[usize::try_from(index).unwrap()]),
|
||||
expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Head_IncludesUniversalTattoo::test 578423fedcd5e4ed4e53b3d7d80c24a9c8ce30b35db13a09bdf8f47312b7da87 translated
|
||||
#[test]
|
||||
fn appearance_manager_head_bake_includes_universal_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::Head).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::HeadUniversalTattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_UpperBody_IncludesUniversalTattoo::test 6d95989bf8380348714a0ba9ae4c04a85ea64ae47ffc94aaa841ce64810abebd translated
|
||||
#[test]
|
||||
fn appearance_manager_upper_body_bake_includes_universal_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::UpperBody).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::UpperUniversalTattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_LowerBody_IncludesUniversalTattoo::test a21524c69c8bd32610e8cfa405a3cb3eae0a48add62d40a281f9311ebe739ffb translated
|
||||
#[test]
|
||||
fn appearance_manager_lower_body_bake_includes_universal_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::LowerBody).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::LowerUniversalTattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Eyes_IncludesTattoo::test 606c6bad5f911d070c5d8126004d5a1e1dfd4887a115e8dd1f69f2d36bf53ac6 translated
|
||||
#[test]
|
||||
fn appearance_manager_eyes_bake_includes_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::Eyes).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::EyesTattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Skirt_IncludesTattoo::test 7a38a59414bc74221bfbdc8889ef60714a4c6b4f26c9bd47e8f41bfa5a5da811 translated
|
||||
#[test]
|
||||
fn appearance_manager_skirt_bake_includes_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::Skirt).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::SkirtTattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Hair_IncludesHairTattoo::test c9a8c6a0dce259103fb466eb571785eb3c9395c8fa144f1a02d42ae73c0d8253 translated
|
||||
#[test]
|
||||
fn appearance_manager_hair_bake_includes_hair_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::Hair).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::HairTattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedLeftArm_ContainsLeftArmTattoo::test bbbb01e8e009489967b36f22d83c6f326e295b9aabcbb58c00d82bab4e803f66 translated
|
||||
#[test]
|
||||
fn appearance_manager_left_arm_bake_contains_only_left_arm_tattoo() {
|
||||
let textures = AppearanceManager::bake_type_to_textures(BakeType::BakedLeftArm)
|
||||
.expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::LeftArmTattoo));
|
||||
assert_eq!(textures.len(), 1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedLeftLeg_ContainsLeftLegTattoo::test 9d2a25a6ed9cd5a99c206a0fc6d66389959fc5e30dd036302a73fb0b500880b5 translated
|
||||
#[test]
|
||||
fn appearance_manager_left_leg_bake_contains_left_leg_tattoo() {
|
||||
let textures = AppearanceManager::bake_type_to_textures(BakeType::BakedLeftLeg)
|
||||
.expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::LeftLegTattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedAux1_ContainsAux1Tattoo::test b9b0b56e1d4d552f2b43e5e570f3fc1a1f8651d8e77055fabcc35b37b5a9f21d translated
|
||||
#[test]
|
||||
fn appearance_manager_aux1_bake_contains_aux1_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::BakedAux1).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::Aux1Tattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedAux2_ContainsAux2Tattoo::test 6be4bdbf667cadd673afbb1dafa8f4c1844ac9c34464fe5bbbc62f8ebe705b4d translated
|
||||
#[test]
|
||||
fn appearance_manager_aux2_bake_contains_aux2_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::BakedAux2).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::Aux2Tattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedAux3_ContainsAux3Tattoo::test 5d7530c72824f8baf6044fb122d224da61fff1b6cfbf3114ac2f24b1418675d2 translated
|
||||
#[test]
|
||||
fn appearance_manager_aux3_bake_contains_aux3_tattoo() {
|
||||
let textures =
|
||||
AppearanceManager::bake_type_to_textures(BakeType::BakedAux3).expect("BakeTypeToTextures");
|
||||
assert!(textures.contains(&AvatarTextureIndex::Aux3Tattoo));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.MorphLayerForBakeType_ExtendedBakes_ReturnTattooSlots::test 7f05dc0b59adce3b46c82f7415e91e4c945963d918ad6ad1f0e5c9569ee2220e translated
|
||||
#[test]
|
||||
fn appearance_manager_extended_morph_layers_return_tattoo_slots() {
|
||||
for (bake, texture) in [
|
||||
(BakeType::BakedLeftArm, AvatarTextureIndex::LeftArmTattoo),
|
||||
(BakeType::BakedLeftLeg, AvatarTextureIndex::LeftLegTattoo),
|
||||
(BakeType::BakedAux1, AvatarTextureIndex::Aux1Tattoo),
|
||||
(BakeType::BakedAux2, AvatarTextureIndex::Aux2Tattoo),
|
||||
(BakeType::BakedAux3, AvatarTextureIndex::Aux3Tattoo),
|
||||
] {
|
||||
assert_eq!(
|
||||
AppearanceManager::morph_layer_for_bake_type(bake).expect("MorphLayerForBakeType"),
|
||||
texture
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.TextureProvider_Default_IsGridClientBakingTextureProvider::test afdfbf516988c4ba35dfdb42158218a4815e1b8d146ef958225cf0fe73dfc3a9 translated
|
||||
#[test]
|
||||
fn appearance_manager_default_texture_provider_is_grid_client_provider() {
|
||||
let client = GridClient::new().expect("GridClient constructor");
|
||||
let provider = client.appearance().texture_provider();
|
||||
assert_eq!(
|
||||
provider.as_ref().type_id(),
|
||||
TypeId::of::<GridClientBakingTextureProvider>()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.TextureProvider_CanBeReplaced::test e9c27d5b8717fdac1a9f3d22930709c0dee326909cb3c777b769b0ed2dc35b0c translated
|
||||
#[test]
|
||||
fn appearance_manager_texture_provider_can_be_replaced() {
|
||||
let client = GridClient::new().expect("GridClient constructor");
|
||||
let replacement: Arc<dyn IBakingTextureProvider> = Arc::new(RecordingTextureProvider);
|
||||
client
|
||||
.appearance()
|
||||
.set_texture_provider(Arc::clone(&replacement));
|
||||
let actual = client.appearance().texture_provider();
|
||||
assert!(Arc::ptr_eq(&actual, &replacement));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.LastUpdateReceivedCOFVersion_InitialValue_IsMinusOne::test f43c2d8c99cb597ba7a5d4c87d4585560e888931d84741de2882d05ab17b310a translated
|
||||
#[test]
|
||||
fn appearance_manager_initial_cof_version_is_minus_one() {
|
||||
let client = GridClient::new().expect("GridClient constructor");
|
||||
assert_eq!(client.appearance().last_update_received_cof_version(), -1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.UpdateLastReceivedCOFVersion_HigherVersion_Updates::test 62d82f9ec6d12ec9354f02e7b7e86adb29ccecb8b104ed39a66937495bab1438 translated
|
||||
#[test]
|
||||
fn appearance_manager_higher_cof_version_updates() {
|
||||
let client = GridClient::new().expect("GridClient constructor");
|
||||
client
|
||||
.appearance()
|
||||
.update_last_received_cof_version(5)
|
||||
.expect("UpdateLastReceivedCOFVersion");
|
||||
assert_eq!(client.appearance().last_update_received_cof_version(), 5);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.UpdateLastReceivedCOFVersion_LowerVersion_DoesNotUpdate::test ec5831c7d2c03132d3c7e50f6c0d088ca57f2726b7caf77ac240a9d5e92a77b6 translated
|
||||
#[test]
|
||||
fn appearance_manager_lower_cof_version_does_not_update() {
|
||||
let client = GridClient::new().expect("GridClient constructor");
|
||||
client
|
||||
.appearance()
|
||||
.update_last_received_cof_version(10)
|
||||
.expect("UpdateLastReceivedCOFVersion");
|
||||
client
|
||||
.appearance()
|
||||
.update_last_received_cof_version(7)
|
||||
.expect("UpdateLastReceivedCOFVersion");
|
||||
assert_eq!(client.appearance().last_update_received_cof_version(), 10);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.UpdateLastReceivedCOFVersion_SameVersion_DoesNotChange::test 2e607b33bb8be04e6710e26fe62510f0634900579260accd9ffd720023636deb translated
|
||||
#[test]
|
||||
fn appearance_manager_same_cof_version_does_not_change() {
|
||||
let client = GridClient::new().expect("GridClient constructor");
|
||||
client
|
||||
.appearance()
|
||||
.update_last_received_cof_version(5)
|
||||
.expect("UpdateLastReceivedCOFVersion");
|
||||
client
|
||||
.appearance()
|
||||
.update_last_received_cof_version(5)
|
||||
.expect("UpdateLastReceivedCOFVersion");
|
||||
assert_eq!(client.appearance().last_update_received_cof_version(), 5);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.UpdateLastReceivedCOFVersion_MonotonicallyIncreasing_TracksPeak::test 5789831f288823729299944a8796c67348b932570392f59bf8b6d562cfa1c90c translated
|
||||
#[test]
|
||||
fn appearance_manager_cof_version_tracks_peak() {
|
||||
let client = GridClient::new().expect("GridClient constructor");
|
||||
for version in [1, 3, 2, 7, 5, 10, 9] {
|
||||
client
|
||||
.appearance()
|
||||
.update_last_received_cof_version(version)
|
||||
.expect("UpdateLastReceivedCOFVersion");
|
||||
}
|
||||
assert_eq!(client.appearance().last_update_received_cof_version(), 10);
|
||||
}
|
||||
205
tests/compat/tests/appearance_visual_semantics.rs
Normal file
205
tests/compat/tests/appearance_visual_semantics.rs
Normal file
@@ -0,0 +1,205 @@
|
||||
// Exact Rust translations of LibreMetaverse.Tests/AppearanceTests.cs.
|
||||
// Source SHA-256: 3d1f6a43127ee2c678284fd68572c0e81d1825766cc88e17136111fe8b3b7a86
|
||||
|
||||
use libremetaverse::{
|
||||
AppearanceFlags, Avatar, AvatarAppearanceEventArgs, PrimitiveTextureEntryFace, VisualParam,
|
||||
VisualParams,
|
||||
};
|
||||
use libremetaverse_types::{UUID, Utils};
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn group0_params() -> Vec<VisualParam> {
|
||||
let mut params = VisualParams::params();
|
||||
VisualParams::group0_param_ids()
|
||||
.into_iter()
|
||||
.filter_map(|id| params.0.remove(&id))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn appearance_args(visual_params: Vec<u8>) -> AvatarAppearanceEventArgs {
|
||||
AvatarAppearanceEventArgs::new(
|
||||
None,
|
||||
UUID::zero(),
|
||||
false,
|
||||
PrimitiveTextureEntryFace::new(None).unwrap(),
|
||||
Vec::new(),
|
||||
visual_params,
|
||||
1,
|
||||
0,
|
||||
AppearanceFlags::NONE,
|
||||
0,
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_EmptyArray_ReturnsEmptyDictionary::test 644f412b90d429032a9273d24e89333a1694dc88eec3429a98acf00588315ec5 translated
|
||||
#[test]
|
||||
fn decode_visual_params_empty_array_returns_empty_dictionary() {
|
||||
let mut avatar = Avatar::new().unwrap();
|
||||
avatar.visual_parameters = Vec::new();
|
||||
let decoded = avatar.decode_visual_params().unwrap();
|
||||
assert_eq!(decoded.len(), 0);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_CountMatchesGroup0ParamCount::test 6a9acc7130e3394476392b86334a0ce1cb82253bea2b37ac33cf90a426c7af40 translated
|
||||
#[test]
|
||||
fn decode_visual_params_count_matches_group0_param_count() {
|
||||
let group0 = group0_params();
|
||||
let mut avatar = Avatar::new().unwrap();
|
||||
avatar.visual_parameters = vec![0; group0.len()];
|
||||
let decoded = avatar.decode_visual_params().unwrap();
|
||||
assert!(decoded.len() >= group0.len());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_RoundTrip_DefaultValues::test a0c0727a50b414522f875709240f4056547cb699c6ec1981fbef15488784daf5 translated
|
||||
#[test]
|
||||
fn decode_visual_params_round_trip_default_values() {
|
||||
let params = VisualParams::params();
|
||||
let ids = VisualParams::group0_param_ids();
|
||||
let bytes = ids
|
||||
.iter()
|
||||
.map(|id| {
|
||||
params.0.get(id).map_or(0, |vp| {
|
||||
Utils::float_to_byte(vp.default_value, vp.min_value, vp.max_value).unwrap()
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let mut avatar = Avatar::new().unwrap();
|
||||
avatar.visual_parameters = bytes;
|
||||
let decoded = avatar.decode_visual_params().unwrap();
|
||||
let driven_targets: HashSet<i32> = params
|
||||
.0
|
||||
.values()
|
||||
.filter_map(|param| param.driven_params.as_ref())
|
||||
.flatten()
|
||||
.map(|driven| driven.param_id)
|
||||
.collect();
|
||||
|
||||
for id in ids {
|
||||
let Some(vp) = params.0.get(&id) else {
|
||||
continue;
|
||||
};
|
||||
assert!(
|
||||
decoded.contains_key(&id),
|
||||
"ParamID {id} ({}) missing",
|
||||
vp.name
|
||||
);
|
||||
if driven_targets.contains(&id) {
|
||||
continue;
|
||||
}
|
||||
let encoded = Utils::float_to_byte(vp.default_value, vp.min_value, vp.max_value).unwrap();
|
||||
let expected =
|
||||
Utils::byte_to_float_with_byte_single_single(encoded, vp.min_value, vp.max_value)
|
||||
.unwrap();
|
||||
assert!(
|
||||
(decoded[&id] - expected).abs() <= 1e-5,
|
||||
"ParamID {id} ({})",
|
||||
vp.name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_KeysAreGroup0ParamIDs::test fc4fd3059b01a319af2946ea0c289120a4c2609e7e9a96ac26c039c5042b8b4c translated
|
||||
#[test]
|
||||
fn decode_visual_params_keys_are_group0_param_ids() {
|
||||
let group0 = group0_params();
|
||||
let mut avatar = Avatar::new().unwrap();
|
||||
avatar.visual_parameters = vec![0; group0.len()];
|
||||
let decoded = avatar.decode_visual_params().unwrap();
|
||||
let expected: HashSet<i32> = group0.iter().map(|param| param.param_id).collect();
|
||||
assert!(expected.iter().all(|id| decoded.contains_key(id)));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_TruncatedArray_ReturnsPartialResult::test b017127549e186b3cf85b9fe0cc09811ea1d00efa44e3d863292033cb0691d13 translated
|
||||
#[test]
|
||||
fn decode_visual_params_truncated_array_returns_partial_result() {
|
||||
let mut avatar = Avatar::new().unwrap();
|
||||
avatar.visual_parameters = vec![0; 10];
|
||||
let decoded = avatar.decode_visual_params().unwrap();
|
||||
assert!(decoded.len() >= 10);
|
||||
assert!(decoded.len() < VisualParams::group0_param_ids().len());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_MinValue_DecodesNearParamMin::test 80e0fd97979f91c879add1fc3142a0b619a405e4977120db1d5f42a11a71f3f5 translated
|
||||
#[test]
|
||||
fn decode_visual_params_min_value_decodes_near_param_min() {
|
||||
let group0 = group0_params();
|
||||
let mut avatar = Avatar::new().unwrap();
|
||||
avatar.visual_parameters = vec![0; group0.len()];
|
||||
let decoded = avatar.decode_visual_params().unwrap();
|
||||
for vp in group0 {
|
||||
let upper = vp.min_value + (vp.max_value - vp.min_value) / 255.0 + 1e-5;
|
||||
assert!(
|
||||
decoded[&vp.param_id] <= upper,
|
||||
"ParamID {} ({})",
|
||||
vp.param_id,
|
||||
vp.name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_MaxValue_DecodesNearParamMax::test 31937bc9080b18be4aa98ea44bf73f929ba7862b621406b03c16a4651542f302 translated
|
||||
#[test]
|
||||
fn decode_visual_params_max_value_decodes_near_param_max() {
|
||||
let group0 = group0_params();
|
||||
let mut avatar = Avatar::new().unwrap();
|
||||
avatar.visual_parameters = vec![0xff; group0.len()];
|
||||
let decoded = avatar.decode_visual_params().unwrap();
|
||||
for vp in group0 {
|
||||
let lower = vp.max_value - (vp.max_value - vp.min_value) / 255.0 - 1e-5;
|
||||
assert!(
|
||||
decoded[&vp.param_id] >= lower,
|
||||
"ParamID {} ({})",
|
||||
vp.param_id,
|
||||
vp.name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.AvatarAppearanceEventArgs_DecodeVisualParams_EmptyList_ReturnsEmptyDictionary::test af99909259d531024895ce7ea325b49927a12daa886a35eab3d52e3f8fc76921 translated
|
||||
#[test]
|
||||
fn appearance_event_args_decode_visual_params_empty_list_returns_empty_dictionary() {
|
||||
let decoded = appearance_args(Vec::new()).decode_visual_params().unwrap();
|
||||
assert_eq!(decoded.len(), 0);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.AvatarAppearanceEventArgs_DecodeVisualParams_RoundTrip_DefaultValues::test 0aec57fab35764525195e6c0e08a63ff10a467be684295381731c04e836539b5 translated
|
||||
#[test]
|
||||
fn appearance_event_args_decode_visual_params_round_trip_default_values() {
|
||||
let params = VisualParams::params();
|
||||
let ids = VisualParams::group0_param_ids();
|
||||
let bytes = ids
|
||||
.iter()
|
||||
.map(|id| {
|
||||
params.0.get(id).map_or(0, |vp| {
|
||||
Utils::float_to_byte(vp.default_value, vp.min_value, vp.max_value).unwrap()
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let decoded = appearance_args(bytes).decode_visual_params().unwrap();
|
||||
assert!(decoded.len() >= ids.len());
|
||||
for id in ids {
|
||||
if params.0.contains_key(&id) {
|
||||
assert!(decoded.contains_key(&id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.AvatarAppearanceEventArgs_DecodeVisualParams_MatchesAvatarDecodeVisualParams::test ff87dd3a506027ad248006b3b55d85a18b0810bc5b4e3a72eb81d31ebbe4184a translated
|
||||
#[test]
|
||||
fn appearance_event_args_decode_visual_params_matches_avatar_decode_visual_params() {
|
||||
let group0 = group0_params();
|
||||
let bytes: Vec<u8> = group0
|
||||
.iter()
|
||||
.map(|vp| Utils::float_to_byte(vp.default_value, vp.min_value, vp.max_value).unwrap())
|
||||
.collect();
|
||||
let mut avatar = Avatar::new().unwrap();
|
||||
avatar.visual_parameters = bytes.clone();
|
||||
let from_avatar = avatar.decode_visual_params().unwrap();
|
||||
let from_args = appearance_args(bytes).decode_visual_params().unwrap();
|
||||
assert_eq!(from_args.len(), from_avatar.len());
|
||||
for (id, expected) in from_avatar {
|
||||
assert!(from_args.contains_key(&id));
|
||||
assert!((from_args[&id] - expected).abs() <= 1e-5);
|
||||
}
|
||||
}
|
||||
200
tests/compat/tests/current_outfit_folder_semantics.rs
Normal file
200
tests/compat/tests/current_outfit_folder_semantics.rs
Normal file
@@ -0,0 +1,200 @@
|
||||
// Exact Rust translations of the CurrentOutfitFolderTests fixture in
|
||||
// LibreMetaverse.Tests/CurrentOutfitFolderTests.cs.
|
||||
// Source SHA-256: 07177fff27fbee0d0714286c652253985add3a9401a50e8d7a829ce6c2b3b7a86
|
||||
|
||||
use libremetaverse::appearance::{CurrentOutfitFolder, ICurrentOutfitPolicy};
|
||||
use libremetaverse::{
|
||||
GridClient, InventoryItem, InventoryWearable, NameValue, NameValueClassType,
|
||||
NameValueSendtoType, NameValueValueType, Primitive,
|
||||
};
|
||||
use libremetaverse_compat_tests::block_on;
|
||||
use libremetaverse_types::compat::Object;
|
||||
use libremetaverse_types::{AssetType, Error, UUID};
|
||||
use std::sync::Arc;
|
||||
|
||||
struct TestPolicy;
|
||||
impl ICurrentOutfitPolicy for TestPolicy {}
|
||||
|
||||
fn outfit_folder() -> CurrentOutfitFolder {
|
||||
CurrentOutfitFolder::new(Some(Arc::new(GridClient::new().unwrap()))).unwrap()
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.Constructor_WithNullClient_ThrowsArgumentNullException::test 243079029ec81f92ffbc587007a2421389963f72c7843786c5b9a8634a7ddca3 translated
|
||||
#[test]
|
||||
fn constructor_with_null_client_throws_argument_null_exception() {
|
||||
match CurrentOutfitFolder::new(None) {
|
||||
Err(error) => assert_eq!(error, Error::ArgumentNull),
|
||||
Ok(_) => panic!("expected ArgumentNull for client"),
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.Dispose_CalledOnce_DoesNotThrow::test 1d0daac0bfa091bc3c3bffddc32a1511295dd7101f8ab5dfbf305b13b9ac7405 translated
|
||||
#[test]
|
||||
fn dispose_called_once_does_not_throw() {
|
||||
outfit_folder().dispose().unwrap();
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.Dispose_CalledMultipleTimes_DoesNotThrow::test 124b41c342a295f02e9d5991d1dead0ff3e9a780f96424b88f75117ca206460b translated
|
||||
#[test]
|
||||
fn dispose_called_multiple_times_does_not_throw() {
|
||||
let cof = outfit_folder();
|
||||
cof.dispose().unwrap();
|
||||
cof.dispose().unwrap();
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.MaxClothingLayers_Returns60::test e35e779b342fdb54bb7f5b2061f70c35ccc3f7f9ba87f48b2697f24c10f94397 translated
|
||||
#[test]
|
||||
fn max_clothing_layers_returns_60() {
|
||||
assert_eq!(outfit_folder().max_clothing_layers(), 60);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.COF_InitiallyNull::test 2dee4e58f3f53e50c5389ba0594ea0b063af55871eefae49e99bdd4b5c28e552 translated
|
||||
#[test]
|
||||
fn cof_initially_null() {
|
||||
assert!(outfit_folder().cof().is_none());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.AddPolicy_WithValidPolicy_ReturnsAddedPolicy::test 747db5d674a6cb0bc54bcb9d32501d5bab49e0df5e5e39f3781f88d5100ed244 translated
|
||||
#[test]
|
||||
fn add_policy_with_valid_policy_returns_added_policy() {
|
||||
let cof = outfit_folder();
|
||||
let policy: Arc<dyn ICurrentOutfitPolicy> = Arc::new(TestPolicy);
|
||||
let result = cof.add_policy(Arc::clone(&policy)).unwrap();
|
||||
assert!(Arc::ptr_eq(&result, &policy));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.RemovePolicy_WithValidPolicy_DoesNotThrow::test 41f61b917da0410be01b346644a76bc9c800f78d1e1ba6ef805b14cea1b4d00d translated
|
||||
#[test]
|
||||
fn remove_policy_with_valid_policy_does_not_throw() {
|
||||
let cof = outfit_folder();
|
||||
let policy: Arc<dyn ICurrentOutfitPolicy> = Arc::new(TestPolicy);
|
||||
cof.add_policy(Arc::clone(&policy)).unwrap();
|
||||
cof.remove_policy(policy).unwrap();
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.RemovePolicy_WithNonAddedPolicy_DoesNotThrow::test 4add41578d3d5340618cb29ed6969b84c5c3a80e6da09ccb03bc6872a6b6689a translated
|
||||
#[test]
|
||||
fn remove_policy_with_non_added_policy_does_not_throw() {
|
||||
let cof = outfit_folder();
|
||||
cof.remove_policy(Arc::new(TestPolicy)).unwrap();
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.ResolveInventoryLink_WithNonLinkItem_ReturnsSameItem::test 7430a64883f3938afe7da1b126e4ee460cbf2485e2d51035273b4ca8fd150960 translated
|
||||
#[test]
|
||||
fn resolve_inventory_link_with_non_link_item_returns_same_item() {
|
||||
let cof = outfit_folder();
|
||||
let mut wearable = InventoryWearable::new(UUID::random().unwrap()).unwrap();
|
||||
wearable.base.set_asset_type(AssetType::Clothing);
|
||||
wearable.base.set_asset_uuid(UUID::random().unwrap());
|
||||
let item = Arc::new(wearable.base);
|
||||
let result = cof
|
||||
.resolve_inventory_link(Arc::clone(&item))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert!(Arc::ptr_eq(&result, &item));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.ResolveInventoryLink_WithLinkItemNotInStore_ReturnsNull::test 21e0dae8c038d2381eef736ad30d48fc0247e0a55b86e75de02982290a3a9bd0 translated
|
||||
#[test]
|
||||
fn resolve_inventory_link_with_link_item_not_in_store_returns_null() {
|
||||
let mut client = GridClient::new().unwrap();
|
||||
let owner = client.self_().agent_id();
|
||||
let cof = CurrentOutfitFolder::new(Some(Arc::new(client))).unwrap();
|
||||
let mut link = InventoryItem::new_with_uuid(UUID::random().unwrap()).unwrap();
|
||||
link.set_asset_type(AssetType::Link);
|
||||
link.set_asset_uuid(UUID::random().unwrap());
|
||||
link.base.set_owner_id(owner);
|
||||
assert!(
|
||||
cof.resolve_inventory_link(Arc::new(link))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.GetAttachmentItemID_WithNoNameValues_ReturnsZero::test c9e017a587c37b694484feda4fab81ef7f2bb098bbf8f96f3cefbb21f1a568d8 translated
|
||||
#[test]
|
||||
fn get_attachment_item_id_with_no_name_values_returns_zero() {
|
||||
let mut prim = Primitive::new_with_constructor().unwrap();
|
||||
prim.name_values = None;
|
||||
assert_eq!(
|
||||
CurrentOutfitFolder::get_attachment_item_id(prim).unwrap(),
|
||||
UUID::zero()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.GetAttachmentItemID_WithAttachItemID_ReturnsCorrectUUID::test 23e6be11056b93d75424c23030e1d2082545f686d12c0aa14f66991664e347e8 translated
|
||||
#[test]
|
||||
fn get_attachment_item_id_with_attach_item_id_returns_correct_uuid() {
|
||||
let expected = UUID::random().unwrap();
|
||||
let value = NameValue::new_with_string_value_type_class_type_sendto_type_object(
|
||||
"AttachItemID".into(),
|
||||
NameValueValueType::String,
|
||||
NameValueClassType::ReadOnly,
|
||||
NameValueSendtoType::SimViewer,
|
||||
Object::String(expected.to_string()),
|
||||
)
|
||||
.unwrap();
|
||||
let mut prim = Primitive::new_with_constructor().unwrap();
|
||||
prim.name_values = Some(vec![value]);
|
||||
assert_eq!(
|
||||
CurrentOutfitFolder::get_attachment_item_id(prim).unwrap(),
|
||||
expected
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.GetAttachmentItemID_WithoutAttachItemID_ReturnsZero::test 7ee12fc59c8b5e5cb074e18c2af48c0f1b1d7be0937db65a7056e29e114b691f translated
|
||||
#[test]
|
||||
fn get_attachment_item_id_without_attach_item_id_returns_zero() {
|
||||
let value = NameValue::new_with_string_value_type_class_type_sendto_type_object(
|
||||
"SomeOtherValue".into(),
|
||||
NameValueValueType::String,
|
||||
NameValueClassType::ReadOnly,
|
||||
NameValueSendtoType::SimViewer,
|
||||
Object::String("test".into()),
|
||||
)
|
||||
.unwrap();
|
||||
let mut prim = Primitive::new_with_constructor().unwrap();
|
||||
prim.name_values = Some(vec![value]);
|
||||
assert_eq!(
|
||||
CurrentOutfitFolder::get_attachment_item_id(prim).unwrap(),
|
||||
UUID::zero()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.IsObjectDescendentOf_WithZeroParentId_ReturnsFalse::test a878c220510aacbf61ebfb192952e26d96343312fcf9648e57e270e29aaa9d5d translated
|
||||
#[test]
|
||||
fn is_object_descendent_of_with_zero_parent_id_returns_false() {
|
||||
let cof = outfit_folder();
|
||||
let item = InventoryItem::new_with_uuid(UUID::random().unwrap()).unwrap();
|
||||
assert!(!block_on(cof.is_object_descendent_of(item.base, UUID::zero(), None)).unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.IsObjectDescendentOf_WithDirectParent_ReturnsTrue::test ac3af5edef5ee67058a91a990bfde38e616d00919b0cd8e0b5f7345f7d8dab6c translated
|
||||
#[test]
|
||||
fn is_object_descendent_of_with_direct_parent_returns_true() {
|
||||
let cof = outfit_folder();
|
||||
let parent = UUID::random().unwrap();
|
||||
let mut item = InventoryItem::new_with_uuid(UUID::random().unwrap()).unwrap();
|
||||
item.base.set_parent_uuid(parent);
|
||||
assert!(block_on(cof.is_object_descendent_of(item.base, parent, None)).unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.FetchParent_WithZeroParentUUID_ReturnsNull::test ee6cc0cc9a48ec07afb8bd7fa8e1c53c2db258be11e2848ee5752e41eb34e45a translated
|
||||
#[test]
|
||||
fn fetch_parent_with_zero_parent_uuid_returns_null() {
|
||||
let cof = outfit_folder();
|
||||
let mut item = InventoryItem::new_with_uuid(UUID::random().unwrap()).unwrap();
|
||||
item.base.set_parent_uuid(UUID::zero());
|
||||
assert!(
|
||||
block_on(cof.fetch_parent(item.base, None))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.GetCurrentOutfitLinks_WithNullCOF_ReturnsEmptyList::test 5c0d475ccd4423bc099eb141f36061fdfaa589fd36d27c907d03a9d0be3f6f48 translated
|
||||
#[test]
|
||||
fn get_current_outfit_links_with_null_cof_returns_empty_list() {
|
||||
let links = block_on(outfit_folder().get_current_outfit_links(None)).unwrap();
|
||||
assert!(links.is_empty());
|
||||
}
|
||||
415
tests/compat/tests/current_outfit_policy_semantics.rs
Normal file
415
tests/compat/tests/current_outfit_policy_semantics.rs
Normal file
@@ -0,0 +1,415 @@
|
||||
// Exact Rust translations of the CompositeCurrentOutfitPolicyTests fixture in
|
||||
// LibreMetaverse.Tests/CurrentOutfitFolderTests.cs.
|
||||
// Source SHA-256: 07177fff27fbee0d0714286c652253985add3a9401a50e8d7a829ce6c2b3b7a86
|
||||
|
||||
use libremetaverse::appearance::{CompositeCurrentOutfitPolicy, ICurrentOutfitPolicy};
|
||||
use libremetaverse::{InventoryItem, InventoryWearable};
|
||||
use libremetaverse_compat_tests::block_on;
|
||||
use libremetaverse_types::compat::{CancellationToken, CancellationTokenSource};
|
||||
use libremetaverse_types::{AssetType, Error, UUID};
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
struct TestPolicy {
|
||||
allow_attach: AtomicBool,
|
||||
allow_detach: AtomicBool,
|
||||
attach_calls: AtomicUsize,
|
||||
detach_calls: AtomicUsize,
|
||||
report_calls: AtomicUsize,
|
||||
last_added: Mutex<Option<Arc<Vec<InventoryItem>>>>,
|
||||
last_removed: Mutex<Option<Arc<Vec<InventoryItem>>>>,
|
||||
}
|
||||
|
||||
impl TestPolicy {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
allow_attach: AtomicBool::new(true),
|
||||
allow_detach: AtomicBool::new(true),
|
||||
attach_calls: AtomicUsize::new(0),
|
||||
detach_calls: AtomicUsize::new(0),
|
||||
report_calls: AtomicUsize::new(0),
|
||||
last_added: Mutex::new(None),
|
||||
last_removed: Mutex::new(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ICurrentOutfitPolicy for TestPolicy {
|
||||
fn can_attach(&self, _item: Option<Arc<InventoryItem>>) -> Result<bool, Error> {
|
||||
self.attach_calls.fetch_add(1, Ordering::SeqCst);
|
||||
Ok(self.allow_attach.load(Ordering::SeqCst))
|
||||
}
|
||||
|
||||
fn can_detach(&self, _item: Option<Arc<InventoryItem>>) -> Result<bool, Error> {
|
||||
self.detach_calls.fetch_add(1, Ordering::SeqCst);
|
||||
Ok(self.allow_detach.load(Ordering::SeqCst))
|
||||
}
|
||||
|
||||
fn report_item_change(
|
||||
&self,
|
||||
added: Option<Arc<Vec<InventoryItem>>>,
|
||||
removed: Option<Arc<Vec<InventoryItem>>>,
|
||||
_cancellation_token: Option<CancellationToken>,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + '_>> {
|
||||
self.report_calls.fetch_add(1, Ordering::SeqCst);
|
||||
*self.last_added.lock().unwrap() = added;
|
||||
*self.last_removed.lock().unwrap() = removed;
|
||||
Box::pin(async { Ok(()) })
|
||||
}
|
||||
}
|
||||
|
||||
fn item() -> Arc<InventoryItem> {
|
||||
let mut wearable = InventoryWearable::new(UUID::random().unwrap()).unwrap();
|
||||
wearable.base.set_asset_type(AssetType::Clothing);
|
||||
wearable.base.base.set_name("Test Item".into());
|
||||
Arc::new(wearable.base)
|
||||
}
|
||||
|
||||
fn as_policy(policy: &Arc<TestPolicy>) -> Arc<dyn ICurrentOutfitPolicy> {
|
||||
policy.clone()
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddPolicy_WithValidPolicy_ReturnsThis::test 31c1829eaa2b82b498cc1eaea131d2e34d1a0b5620be24f4da853c62c49807cc translated
|
||||
#[test]
|
||||
fn add_policy_with_valid_policy_returns_this() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let policy = Arc::new(TestPolicy::new());
|
||||
let result = composite.add_policy(Some(as_policy(&policy))).unwrap();
|
||||
assert!(std::ptr::eq(
|
||||
std::ptr::from_ref(result),
|
||||
std::ptr::from_ref(&composite)
|
||||
));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddPolicy_WithNullPolicy_ThrowsArgumentNullException::test 6a111f0ad2e91c8566b5459939e3ecc76282cd033bb8d6483e1672c36891e597 translated
|
||||
#[test]
|
||||
fn add_policy_with_null_policy_throws_argument_null_exception() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
assert!(matches!(
|
||||
composite.add_policy(None),
|
||||
Err(Error::ArgumentNull)
|
||||
));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddPolicy_MultiplePolicies_AllAreConsulted::test 1767ee3dee6b07e71f10b52613962e211fcf9906a45d12188f517cf751896f24 translated
|
||||
#[test]
|
||||
fn add_policy_multiple_policies_all_are_consulted() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let first = Arc::new(TestPolicy::new());
|
||||
let second = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&first))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&second))).unwrap();
|
||||
first.allow_attach.store(true, Ordering::SeqCst);
|
||||
second.allow_attach.store(true, Ordering::SeqCst);
|
||||
let result = composite.can_attach(Some(item())).unwrap();
|
||||
assert_eq!(first.attach_calls.load(Ordering::SeqCst), 1);
|
||||
assert_eq!(second.attach_calls.load(Ordering::SeqCst), 1);
|
||||
assert!(result);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddPolicy_SamePolicyTwice_OnlyAddsOnce::test e3d1340780680bfc46267194ddb3c47e4ae24299cf532d92dd71d9770f1955fa translated
|
||||
#[test]
|
||||
fn add_policy_same_policy_twice_only_adds_once() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let policy = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&policy))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&policy))).unwrap();
|
||||
policy.allow_attach.store(true, Ordering::SeqCst);
|
||||
composite.can_attach(Some(item())).unwrap();
|
||||
assert_eq!(policy.attach_calls.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.RemovePolicy_WithAddedPolicy_RemovesPolicy::test 9dd407dceeacdcc60fccb0d9869ad261d90acd74ae4257331e0cf8d4be2ee603 translated
|
||||
#[test]
|
||||
fn remove_policy_with_added_policy_removes_policy() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let policy = Arc::new(TestPolicy::new());
|
||||
let policy_dyn = as_policy(&policy);
|
||||
composite.add_policy(Some(Arc::clone(&policy_dyn))).unwrap();
|
||||
composite.remove_policy(Some(policy_dyn)).unwrap();
|
||||
policy.allow_attach.store(false, Ordering::SeqCst);
|
||||
assert!(composite.can_attach(Some(item())).unwrap());
|
||||
assert_eq!(policy.attach_calls.load(Ordering::SeqCst), 0);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.RemovePolicy_WithNonAddedPolicy_DoesNotThrow::test 9fa18bd628f6f02912168309e8e2afb6346a73a235dcc16cc81bc35e2dcf766f translated
|
||||
#[test]
|
||||
fn remove_policy_with_non_added_policy_does_not_throw() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
composite
|
||||
.remove_policy(Some(Arc::new(TestPolicy::new())))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.RemovePolicy_WithNull_DoesNotThrow::test 28075d5f7c5458f1ccdf9981970e212e1663a9e5ebee65fce636a11a22390bfb translated
|
||||
#[test]
|
||||
fn remove_policy_with_null_does_not_throw() {
|
||||
CompositeCurrentOutfitPolicy::new()
|
||||
.unwrap()
|
||||
.remove_policy(None)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithNoPolicies_ReturnsTrue::test 74bc06bb6cedfe84a3cd7e5b4c32b251ee6eff81c272c7d899436dbd7f21886b translated
|
||||
#[test]
|
||||
fn can_attach_with_no_policies_returns_true() {
|
||||
assert!(
|
||||
CompositeCurrentOutfitPolicy::new()
|
||||
.unwrap()
|
||||
.can_attach(Some(item()))
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithNullItem_ThrowsArgumentNullException::test a47ebf9c89b603c10109c6e643de5043ba13cd2eaf5f04d73ab1fd5f40e9b332 translated
|
||||
#[test]
|
||||
fn can_attach_with_null_item_throws_argument_null_exception() {
|
||||
assert!(matches!(
|
||||
CompositeCurrentOutfitPolicy::new()
|
||||
.unwrap()
|
||||
.can_attach(None),
|
||||
Err(Error::ArgumentNull)
|
||||
));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithAllPoliciesAllowing_ReturnsTrue::test 32c2f5dcc5cbdf24e4205c25c833aaa3c0f203aeb8ff20c30fdac1264f12f6bd translated
|
||||
#[test]
|
||||
fn can_attach_with_all_policies_allowing_returns_true() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let first = Arc::new(TestPolicy::new());
|
||||
let second = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&first))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&second))).unwrap();
|
||||
first.allow_attach.store(true, Ordering::SeqCst);
|
||||
second.allow_attach.store(true, Ordering::SeqCst);
|
||||
assert!(composite.can_attach(Some(item())).unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithOnePolicyDenying_ReturnsFalse::test f38d910142a563bded6d35b969c0c560ffa072fd8df073a15fbbbed745681d0d translated
|
||||
#[test]
|
||||
fn can_attach_with_one_policy_denying_returns_false() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let first = Arc::new(TestPolicy::new());
|
||||
let second = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&first))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&second))).unwrap();
|
||||
first.allow_attach.store(true, Ordering::SeqCst);
|
||||
second.allow_attach.store(false, Ordering::SeqCst);
|
||||
assert!(!composite.can_attach(Some(item())).unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithAllPoliciesDenying_ReturnsFalse::test 6cdda22d59a3cd690a187b597a7c8a2474e43c27902e737f15f0c71adc5bcf7c translated
|
||||
#[test]
|
||||
fn can_attach_with_all_policies_denying_returns_false() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let first = Arc::new(TestPolicy::new());
|
||||
let second = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&first))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&second))).unwrap();
|
||||
first.allow_attach.store(false, Ordering::SeqCst);
|
||||
second.allow_attach.store(false, Ordering::SeqCst);
|
||||
assert!(!composite.can_attach(Some(item())).unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithNoPolicies_ReturnsTrue::test fe53b90f59fd9a73c4af1b7071f04cae0a7b623d6a50a3d8eb2fcae82e6872e9 translated
|
||||
#[test]
|
||||
fn can_detach_with_no_policies_returns_true() {
|
||||
assert!(
|
||||
CompositeCurrentOutfitPolicy::new()
|
||||
.unwrap()
|
||||
.can_detach(Some(item()))
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithNullItem_ThrowsArgumentNullException::test 8a39f9c6e26f3a136de641f38507db144f731aed0861edbeafcfdb70306ecffb translated
|
||||
#[test]
|
||||
fn can_detach_with_null_item_throws_argument_null_exception() {
|
||||
assert!(matches!(
|
||||
CompositeCurrentOutfitPolicy::new()
|
||||
.unwrap()
|
||||
.can_detach(None),
|
||||
Err(Error::ArgumentNull)
|
||||
));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithAllPoliciesAllowing_ReturnsTrue::test 2cbe1f0a5907c1dfa01af4329fa64177463798ec6caa357c8da8f5d3291901bf translated
|
||||
#[test]
|
||||
fn can_detach_with_all_policies_allowing_returns_true() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let first = Arc::new(TestPolicy::new());
|
||||
let second = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&first))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&second))).unwrap();
|
||||
first.allow_detach.store(true, Ordering::SeqCst);
|
||||
second.allow_detach.store(true, Ordering::SeqCst);
|
||||
assert!(composite.can_detach(Some(item())).unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithOnePolicyDenying_ReturnsFalse::test 11896040dd8e4b5bbd7d85a1da126c648ad77eb349a73edf1e18fa5710cde1c9 translated
|
||||
#[test]
|
||||
fn can_detach_with_one_policy_denying_returns_false() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let first = Arc::new(TestPolicy::new());
|
||||
let second = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&first))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&second))).unwrap();
|
||||
first.allow_detach.store(true, Ordering::SeqCst);
|
||||
second.allow_detach.store(false, Ordering::SeqCst);
|
||||
assert!(!composite.can_detach(Some(item())).unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithAllPoliciesDenying_ReturnsFalse::test 62b8478f593f2bf16b44267d80668e327a245d0b5c0386e7229a5857d669ae6c translated
|
||||
#[test]
|
||||
fn can_detach_with_all_policies_denying_returns_false() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let first = Arc::new(TestPolicy::new());
|
||||
let second = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&first))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&second))).unwrap();
|
||||
first.allow_detach.store(false, Ordering::SeqCst);
|
||||
second.allow_detach.store(false, Ordering::SeqCst);
|
||||
assert!(!composite.can_detach(Some(item())).unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithNoPolicies_CompletesSuccessfully::test e3f6824512503bea532826b9a9e4f7bb5abdea53f962fbbc6fdae299a6fe44a0 translated
|
||||
#[test]
|
||||
fn report_item_change_with_no_policies_completes_successfully() {
|
||||
let added = Arc::new(vec![Arc::try_unwrap(item()).ok().unwrap()]);
|
||||
let removed = Arc::new(Vec::new());
|
||||
block_on(
|
||||
CompositeCurrentOutfitPolicy::new()
|
||||
.unwrap()
|
||||
.report_item_change(Some(added), Some(removed), None),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithMultiplePolicies_CallsAllPolicies::test 4797cc1851d78364553dac59a6f9a894107fa04fb3fddfb52ed0e4fb5b4bcd1a translated
|
||||
#[test]
|
||||
fn report_item_change_with_multiple_policies_calls_all_policies() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let first = Arc::new(TestPolicy::new());
|
||||
let second = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&first))).unwrap();
|
||||
composite.add_policy(Some(as_policy(&second))).unwrap();
|
||||
let added = Arc::new(vec![Arc::try_unwrap(item()).ok().unwrap()]);
|
||||
let removed = Arc::new(Vec::new());
|
||||
block_on(composite.report_item_change(
|
||||
Some(Arc::clone(&added)),
|
||||
Some(Arc::clone(&removed)),
|
||||
None,
|
||||
))
|
||||
.unwrap();
|
||||
assert_eq!(first.report_calls.load(Ordering::SeqCst), 1);
|
||||
assert_eq!(second.report_calls.load(Ordering::SeqCst), 1);
|
||||
assert!(Arc::ptr_eq(
|
||||
first.last_added.lock().unwrap().as_ref().unwrap(),
|
||||
&added
|
||||
));
|
||||
assert!(Arc::ptr_eq(
|
||||
second.last_added.lock().unwrap().as_ref().unwrap(),
|
||||
&added
|
||||
));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithCancelledToken_ThrowsOperationCanceledException::test e4eaf9c1ee2d55a3e6c7bca634ff1af2a0e19b7560ea616984d258df46ec89fd translated
|
||||
#[test]
|
||||
fn report_item_change_with_cancelled_token_throws_operation_cancelled_exception() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
composite
|
||||
.add_policy(Some(Arc::new(TestPolicy::new())))
|
||||
.unwrap();
|
||||
let source = CancellationTokenSource::new();
|
||||
source.cancel();
|
||||
let added = Arc::new(vec![Arc::try_unwrap(item()).ok().unwrap()]);
|
||||
let error = block_on(composite.report_item_change(
|
||||
Some(added),
|
||||
Some(Arc::new(Vec::new())),
|
||||
Some(source.token()),
|
||||
))
|
||||
.unwrap_err();
|
||||
assert_eq!(error, Error::Cancelled);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithEmptyLists_DoesNotThrow::test 6ba7e22fb7425e523f301612f7d7f6aed88e7d422050a70137d93b4a8004ae50 translated
|
||||
#[test]
|
||||
fn report_item_change_with_empty_lists_does_not_throw() {
|
||||
let composite = CompositeCurrentOutfitPolicy::new().unwrap();
|
||||
let policy = Arc::new(TestPolicy::new());
|
||||
composite.add_policy(Some(as_policy(&policy))).unwrap();
|
||||
block_on(composite.report_item_change(
|
||||
Some(Arc::new(Vec::new())),
|
||||
Some(Arc::new(Vec::new())),
|
||||
None,
|
||||
))
|
||||
.unwrap();
|
||||
assert_eq!(policy.report_calls.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithNullLists_DoesNotThrowFromComposite::test c512c54f78c46fb4774d9b5c9c1057627592e1c25267811cddf3d687d3d1ec4d translated
|
||||
#[test]
|
||||
fn report_item_change_with_null_lists_does_not_throw_from_composite() {
|
||||
block_on(
|
||||
CompositeCurrentOutfitPolicy::new()
|
||||
.unwrap()
|
||||
.report_item_change(None, None, None),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddRemovePolicy_ConcurrentAccess_DoesNotThrow::test a73a01065867d90305f491e41d9ea61bc27b80c026672ed920368877bfb0fe14 translated
|
||||
#[test]
|
||||
fn add_remove_policy_concurrent_access_does_not_throw() {
|
||||
let composite = Arc::new(CompositeCurrentOutfitPolicy::new().unwrap());
|
||||
let policies: Vec<Arc<dyn ICurrentOutfitPolicy>> = (0..10)
|
||||
.map(|_| Arc::new(TestPolicy::new()) as Arc<dyn ICurrentOutfitPolicy>)
|
||||
.collect();
|
||||
let mut threads = Vec::new();
|
||||
for policy in &policies {
|
||||
let composite = Arc::clone(&composite);
|
||||
let policy = Arc::clone(policy);
|
||||
threads.push(std::thread::spawn(move || {
|
||||
composite.add_policy(Some(policy)).map(|_| ())
|
||||
}));
|
||||
}
|
||||
for policy in policies {
|
||||
let composite = Arc::clone(&composite);
|
||||
threads.push(std::thread::spawn(move || {
|
||||
composite.remove_policy(Some(policy))
|
||||
}));
|
||||
}
|
||||
for thread in threads {
|
||||
thread.join().unwrap().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WhileModifyingPolicies_DoesNotThrow::test 697999feeb776fae9a47cb9678c0ae0234d3b3831ce40c0e6f50fe622a5cc2b7 translated
|
||||
#[test]
|
||||
fn can_attach_while_modifying_policies_does_not_throw() {
|
||||
let composite = Arc::new(CompositeCurrentOutfitPolicy::new().unwrap());
|
||||
let stop = Arc::new(AtomicBool::new(false));
|
||||
let read_composite = Arc::clone(&composite);
|
||||
let read_stop = Arc::clone(&stop);
|
||||
let test_item = item();
|
||||
let reader = std::thread::spawn(move || {
|
||||
while !read_stop.load(Ordering::SeqCst) {
|
||||
let _ = read_composite.can_attach(Some(Arc::clone(&test_item)));
|
||||
}
|
||||
});
|
||||
let write_composite = Arc::clone(&composite);
|
||||
let writer = std::thread::spawn(move || {
|
||||
for _ in 0..100 {
|
||||
let policy: Arc<dyn ICurrentOutfitPolicy> = Arc::new(TestPolicy::new());
|
||||
write_composite
|
||||
.add_policy(Some(Arc::clone(&policy)))
|
||||
.unwrap();
|
||||
write_composite.remove_policy(Some(policy)).unwrap();
|
||||
}
|
||||
});
|
||||
writer.join().unwrap();
|
||||
stop.store(true, Ordering::SeqCst);
|
||||
reader.join().unwrap();
|
||||
}
|
||||
@@ -2,77 +2,6 @@
|
||||
// Source: LibreMetaverse 2aa70bb68513b39795da5d13c88f31b86e85a3ba
|
||||
// Pending cases are catalog entries, not fake executable Rust tests.
|
||||
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.COF_IsInitializedAfterLogin::test 7029854dc6f4e03016e2ea274140cd9adbbad6b8c11b58cf9e728d9a4cf37f81
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.COF_HasExpectedFolderName::test 9a8cee3c3958b8631921aaa6b43f69dc430eee9bd3544c8f667aa8f5e858b8ac
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.GetCurrentOutfitLinksAsync_ReturnsLinks::test a1a1c9f926a8b9f4cc4287ab751c4eb70d25a83c1024ef76e53f95c351db8a35
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.GetCurrentOutfitLinksAsync_ContainsAtLeastOneLink::test ef91dfaf7b75f61c97c3957b4dac006a153c7f2d167d6732a9a6dceee08883f2
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.GetWornAt_Shape_ReturnsAtLeastOne::test abc01e346371910610312ff9352ee05c0d317a7c677c0fa8cb398d3b0522c3bf
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.LastUpdateReceivedCOFVersion_AdvancesAfterLogin::test 5371df8b02df9da20b413f4155f63967184dad23f57708beb56a2c6559e78520
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.RequestOwnAvatarTextures_DoesNotThrow_AndMaintainsVersionGuard::test ee8420690fc9714411450beb5be5755b82ddf7ed0d69e9da88b3184339bea744
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceLiveTests.cs::AppearanceLiveTests.COF_MaxClothingLayers_Is60::test aac1292781cb0a4cbf710535036fa6464065f72d1b2c5214a9b7dc918513e8cd
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.WearableTypeToAssetType_BodypartsAndClothing_ReturnsExpected::test 6d0f0d09a6da8121ba828159a75ca1c1ce54329ec48060a6786aa8f807c13ec0
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeIndexToTextureIndex_Matches_BakeTypeToAgentTextureIndex::test c559ea49314b157605346243713fd10480a10f9a97daffd9cac8acccbd39612b
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeIndex_ArrayLength_Equals_BAKED_TEXTURE_COUNT::test b661ca888df5b7fd41e51dfd298fb6d5e30a3a848102006c109b9dc4fc0e165c
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Head_IncludesExpectedSlots::test 44e03523f0e3f6691e527e014bfc38d9ca57c1d310e7cf2c6d7ae8a429a31e1d
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_UpperBody_IncludesExpectedSlots::test fb7650becf6c01c1e7ffd731ac7b6c013957467110c7ed8d5bef9788ee9a5a16
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_LowerBody_Eyes_Skirt_Hair_IncludeExpected::test fad2baeca74cab39305c8f599c5de5777b55c329738db5c55f58a09366870374
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.MorphLayerForBakeType_ReturnsExpectedIndices::test 3051ccea9adec4f9ef824ce967c74e7708b62a2264b98ae22340eb8d1927c44f
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.WearableBakeMap_HasExpectedDimensions_And_FirstLayerContainsShapeAndSkin::test 42c072449d1819c956035d1f0290b90acc1e62b4e1e6309590d0cb6cb41bb375
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToAgentTextureIndex_ReturnsUnknown_ForInvalid::test bc79d717462f06d498050182b6d116cea73f3bc173853f6d7894e3de88b70432
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BAKED_TEXTURE_COUNT_Is11::test 9d34c333f7e143d25964553dedaa1bae79c20e1aead331626f449a3894e31e5b
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakedTextureHash_Has11Entries::test 7b26852cc8c1d7257e3e5f6f936f3870e0a06845f5809cc3000d67eb7590a49e
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakedTextureHash_AllEntriesNonZero::test dc7a4010cfc2f975c0624bc5fbceed414297b1139f734d79786b2bb20d943553
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.WearableBakeMap_Has11Rows::test db6016bcdc90f21095f0723556489ec174603783dc40805b56123e25d7a83312
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.WearableBakeMap_ExtendedRows_AreAllInvalid::test 9b36d72c16980dc3780137dda47afa9cd79ef3a2be0d8ccb20723e1e1ac67f41
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeIndexToTextureIndex_ExtendedBakes_MatchAgentTextureIndex::test c331e94827930443aa3ca327374ec562fc9a294fce3304d7cba9f7e7859e43d3
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Head_IncludesUniversalTattoo::test 578423fedcd5e4ed4e53b3d7d80c24a9c8ce30b35db13a09bdf8f47312b7da87
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_UpperBody_IncludesUniversalTattoo::test 6d95989bf8380348714a0ba9ae4c04a85ea64ae47ffc94aaa841ce64810abebd
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_LowerBody_IncludesUniversalTattoo::test a21524c69c8bd32610e8cfa405a3cb3eae0a48add62d40a281f9311ebe739ffb
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Eyes_IncludesTattoo::test 606c6bad5f911d070c5d8126004d5a1e1dfd4887a115e8dd1f69f2d36bf53ac6
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Skirt_IncludesTattoo::test 7a38a59414bc74221bfbdc8889ef60714a4c6b4f26c9bd47e8f41bfa5a5da811
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_Hair_IncludesHairTattoo::test c9a8c6a0dce259103fb466eb571785eb3c9395c8fa144f1a02d42ae73c0d8253
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedLeftArm_ContainsLeftArmTattoo::test bbbb01e8e009489967b36f22d83c6f326e295b9aabcbb58c00d82bab4e803f66
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedLeftLeg_ContainsLeftLegTattoo::test 9d2a25a6ed9cd5a99c206a0fc6d66389959fc5e30dd036302a73fb0b500880b5
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedAux1_ContainsAux1Tattoo::test b9b0b56e1d4d552f2b43e5e570f3fc1a1f8651d8e77055fabcc35b37b5a9f21d
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedAux2_ContainsAux2Tattoo::test 6be4bdbf667cadd673afbb1dafa8f4c1844ac9c34464fe5bbbc62f8ebe705b4d
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BakeTypeToTextures_BakedAux3_ContainsAux3Tattoo::test 5d7530c72824f8baf6044fb122d224da61fff1b6cfbf3114ac2f24b1418675d2
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.MorphLayerForBakeType_ExtendedBakes_ReturnTattooSlots::test 7f05dc0b59adce3b46c82f7415e91e4c945963d918ad6ad1f0e5c9569ee2220e
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.TextureProvider_Default_IsGridClientBakingTextureProvider::test afdfbf516988c4ba35dfdb42158218a4815e1b8d146ef958225cf0fe73dfc3a9
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.TextureProvider_CanBeReplaced::test e9c27d5b8717fdac1a9f3d22930709c0dee326909cb3c777b769b0ed2dc35b0c
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.LastUpdateReceivedCOFVersion_InitialValue_IsMinusOne::test f43c2d8c99cb597ba7a5d4c87d4585560e888931d84741de2882d05ab17b310a
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.UpdateLastReceivedCOFVersion_HigherVersion_Updates::test 62d82f9ec6d12ec9354f02e7b7e86adb29ccecb8b104ed39a66937495bab1438
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.UpdateLastReceivedCOFVersion_LowerVersion_DoesNotUpdate::test ec5831c7d2c03132d3c7e50f6c0d088ca57f2726b7caf77ac240a9d5e92a77b6
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.UpdateLastReceivedCOFVersion_SameVersion_DoesNotChange::test 2e607b33bb8be04e6710e26fe62510f0634900579260accd9ffd720023636deb
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.UpdateLastReceivedCOFVersion_MonotonicallyIncreasing_TracksPeak::test 5789831f288823729299944a8796c67348b932570392f59bf8b6d562cfa1c90c
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_EmptyArray_ReturnsEmptyDictionary::test 644f412b90d429032a9273d24e89333a1694dc88eec3429a98acf00588315ec5
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_CountMatchesGroup0ParamCount::test 6a9acc7130e3394476392b86334a0ce1cb82253bea2b37ac33cf90a426c7af40
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_RoundTrip_DefaultValues::test a0c0727a50b414522f875709240f4056547cb699c6ec1981fbef15488784daf5
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_KeysAreGroup0ParamIDs::test fc4fd3059b01a319af2946ea0c289120a4c2609e7e9a96ac26c039c5042b8b4c
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_TruncatedArray_ReturnsPartialResult::test b017127549e186b3cf85b9fe0cc09811ea1d00efa44e3d863292033cb0691d13
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_MinValue_DecodesNearParamMin::test 80e0fd97979f91c879add1fc3142a0b619a405e4977120db1d5f42a11a71f3f5
|
||||
// pending-parity-case: LibreMetaverse.Tests/AppearanceTests.cs::AppearanceTests.DecodeVisualParams_MaxValue_DecodesNearParamMax::test 31937bc9080b18be4aa98ea44bf73f929ba7862b621406b03c16a4651542f302
|
||||
// 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/BakerTests.cs::BakerTests.Bake_GrayscaleLayerTexture_DoesNotThrow::test c3fc1d2c16b5f8d69678a6cf05a3a275e0b657f3a6e7f6788f350f2a107200b3
|
||||
// pending-parity-case: LibreMetaverse.Tests/BakerTests.cs::BakerTests.Bake_GrayscaleHairTextureNoSkin_DoesNotThrow::test e48b737d9138e63cda98b5e80bf561a80d1dab5de78901ac9e1bb320ca281eb6
|
||||
// pending-parity-case: LibreMetaverse.Tests/BakerTests.cs::BakerTests.LoadResourceLayer_HeadColorTga_LoadsFromCharacterDirectory::test 5a9b80005a51f04a227ca392218725d50704d038783e04fc49bb955997c22e76
|
||||
// pending-parity-case: LibreMetaverse.Tests/BakerTests.cs::BakerTests.LoadResourceLayer_CachedResourceNotCorruptedByCallerMutation::test 18b458bbd7bb13d2b68711f7d3495193f1b4edac9c1f776930ad2c172f97cd49
|
||||
// pending-parity-case: LibreMetaverse.Tests/BakerTests.cs::BakerTests.ResizeToBakeDimensions_SourceSmallerInOneAxisOnly_ScalesRatherThanTiles::test ce5bd346b48cb19dbc0248403eafefb07309d4e05e675e9a02db5a46d7cd65ff
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.GetCofLinkDescription_ClothingWearable_ReturnsWearableTypeAndZeroLayer::test 898a14ff28d953a58a01c3a0e5d9d9fcbbe61376a33fdc5caf20268aaac76242
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.GetCofLinkDescription_BodyPartShape_ReturnsEmpty::test 4f009136d265da91afb9eafd060faf459f6c510ca0502a33ce9e128d241f9bd1
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.GetCofLinkDescription_AttachmentObject_ReturnsEmpty::test a838329a7a23081a4022671bc794e7e706c9ab7da51598280a8befbb824d336d
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.GetCofLinkDescription_AllBodyPartTypes_ReturnEmpty::test aa057d55a3b34846567efe382b6e090b5d91935a4ffa6166093b34870ee5da23
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateInventoryLinksAsync_SuccessResponse_ReturnsAllParsedLinks::test 416a1f023a2ae3b883c4c49f0a774c84a2f1a3562abb3ec848f86fe53d929f63
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateInventoryLinksAsync_ServerError_ThrowsHttpRequestException::test 53e3956676e546ab8d69bb63a071028b29151013b6362c39f37516a36cad6641
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateInventoryLinksAsync_NoCapability_ReturnsEmptyList::test d9cd50e620f69e40daab52d175886f3052d3741c5d39ef42549283ff6b2b7b44
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateLinksAsync_EmptyList_InvokesCallbackWithTrueWithoutHttpCall::test e7ba88352761ca9fd3e956233e3743689b41f47bba09bfbb463c66f132273c70
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateLinksAsync_AisAvailable_SendsSingleBatchPost::test 369d99d37dca818991aca94d6ff9d7881874d74797c7a8b705c5925723e383db
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateLinksAsync_AisAvailable_PayloadContainsCorrectFieldsForEachLink::test b7629c3d061fe297e1c1c4f41ca4f8ce9cdeb2764525421be7bdc553a5f83063
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateLinksAsync_AisAvailable_CallbackTrueOnSuccess::test 22dc685f896ec0415e56c1c01846ad90a9757cf5d9a0ed0d3706a76ee325d92d
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateLinksAsync_ServerError_CallbackFalse::test 5fd9b2967bc61933cea80e01c55ee809f6ade246f10fb4048ec2668e0cc71dbf
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.GetCategoryLinks_UsesGetWithNoTidParameter::test 3079c03ab4b14d4ac10a410b3685f1593ea267c52de7b6323f9e8e8387314f29
|
||||
// pending-parity-case: LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.GetCategory_UsesGetWithNoTidParameter::test 98cd0aa58ce9640263d07aecd45337113b07acfc76640d17c5812abe05d35c73
|
||||
// pending-parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.InventoryAISClient_Null_Throws::test ac92e375efc45c50b37e6c82aea372d605fceb470ce053a025e05ff47a5c7121
|
||||
// pending-parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.GridManager_Null_Throws::test e972a95f334b0f46948cda34c27124c28c44faf4372d0e598d7dc60050b49be4
|
||||
// pending-parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.InventoryManager_Null_Throws::test 5e7498066c944800354abbc71eea825fe90d0c40a25a6065967a3ebcc9efea74
|
||||
@@ -80,47 +9,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/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
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.MaxClothingLayers_Returns60::test e35e779b342fdb54bb7f5b2061f70c35ccc3f7f9ba87f48b2697f24c10f94397
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.COF_InitiallyNull::test 2dee4e58f3f53e50c5389ba0594ea0b063af55871eefae49e99bdd4b5c28e552
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.AddPolicy_WithValidPolicy_ReturnsAddedPolicy::test 747db5d674a6cb0bc54bcb9d32501d5bab49e0df5e5e39f3781f88d5100ed244
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.RemovePolicy_WithValidPolicy_DoesNotThrow::test 41f61b917da0410be01b346644a76bc9c800f78d1e1ba6ef805b14cea1b4d00d
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.RemovePolicy_WithNonAddedPolicy_DoesNotThrow::test 4add41578d3d5340618cb29ed6969b84c5c3a80e6da09ccb03bc6872a6b6689a
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.ResolveInventoryLink_WithNonLinkItem_ReturnsSameItem::test 7430a64883f3938afe7da1b126e4ee460cbf2485e2d51035273b4ca8fd150960
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.ResolveInventoryLink_WithLinkItemNotInStore_ReturnsNull::test 21e0dae8c038d2381eef736ad30d48fc0247e0a55b86e75de02982290a3a9bd0
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.GetAttachmentItemID_WithNoNameValues_ReturnsZero::test c9e017a587c37b694484feda4fab81ef7f2bb098bbf8f96f3cefbb21f1a568d8
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.GetAttachmentItemID_WithAttachItemID_ReturnsCorrectUUID::test 23e6be11056b93d75424c23030e1d2082545f686d12c0aa14f66991664e347e8
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.GetAttachmentItemID_WithoutAttachItemID_ReturnsZero::test 7ee12fc59c8b5e5cb074e18c2af48c0f1b1d7be0937db65a7056e29e114b691f
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.IsObjectDescendentOf_WithZeroParentId_ReturnsFalse::test a878c220510aacbf61ebfb192952e26d96343312fcf9648e57e270e29aaa9d5d
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.IsObjectDescendentOf_WithDirectParent_ReturnsTrue::test ac3af5edef5ee67058a91a990bfde38e616d00919b0cd8e0b5f7345f7d8dab6c
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.FetchParent_WithZeroParentUUID_ReturnsNull::test ee6cc0cc9a48ec07afb8bd7fa8e1c53c2db258be11e2848ee5752e41eb34e45a
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CurrentOutfitFolderTests.GetCurrentOutfitLinks_WithNullCOF_ReturnsEmptyList::test 5c0d475ccd4423bc099eb141f36061fdfaa589fd36d27c907d03a9d0be3f6f48
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddPolicy_WithValidPolicy_ReturnsThis::test 31c1829eaa2b82b498cc1eaea131d2e34d1a0b5620be24f4da853c62c49807cc
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddPolicy_WithNullPolicy_ThrowsArgumentNullException::test 6a111f0ad2e91c8566b5459939e3ecc76282cd033bb8d6483e1672c36891e597
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddPolicy_MultiplePolicies_AllAreConsulted::test 1767ee3dee6b07e71f10b52613962e211fcf9906a45d12188f517cf751896f24
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddPolicy_SamePolicyTwice_OnlyAddsOnce::test e3d1340780680bfc46267194ddb3c47e4ae24299cf532d92dd71d9770f1955fa
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.RemovePolicy_WithAddedPolicy_RemovesPolicy::test 9dd407dceeacdcc60fccb0d9869ad261d90acd74ae4257331e0cf8d4be2ee603
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.RemovePolicy_WithNonAddedPolicy_DoesNotThrow::test 9fa18bd628f6f02912168309e8e2afb6346a73a235dcc16cc81bc35e2dcf766f
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.RemovePolicy_WithNull_DoesNotThrow::test 28075d5f7c5458f1ccdf9981970e212e1663a9e5ebee65fce636a11a22390bfb
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithNoPolicies_ReturnsTrue::test 74bc06bb6cedfe84a3cd7e5b4c32b251ee6eff81c272c7d899436dbd7f21886b
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithNullItem_ThrowsArgumentNullException::test a47ebf9c89b603c10109c6e643de5043ba13cd2eaf5f04d73ab1fd5f40e9b332
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithAllPoliciesAllowing_ReturnsTrue::test 32c2f5dcc5cbdf24e4205c25c833aaa3c0f203aeb8ff20c30fdac1264f12f6bd
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithOnePolicyDenying_ReturnsFalse::test f38d910142a563bded6d35b969c0c560ffa072fd8df073a15fbbbed745681d0d
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WithAllPoliciesDenying_ReturnsFalse::test 6cdda22d59a3cd690a187b597a7c8a2474e43c27902e737f15f0c71adc5bcf7c
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithNoPolicies_ReturnsTrue::test fe53b90f59fd9a73c4af1b7071f04cae0a7b623d6a50a3d8eb2fcae82e6872e9
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithNullItem_ThrowsArgumentNullException::test 8a39f9c6e26f3a136de641f38507db144f731aed0861edbeafcfdb70306ecffb
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithAllPoliciesAllowing_ReturnsTrue::test 2cbe1f0a5907c1dfa01af4329fa64177463798ec6caa357c8da8f5d3291901bf
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithOnePolicyDenying_ReturnsFalse::test 11896040dd8e4b5bbd7d85a1da126c648ad77eb349a73edf1e18fa5710cde1c9
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanDetach_WithAllPoliciesDenying_ReturnsFalse::test 62b8478f593f2bf16b44267d80668e327a245d0b5c0386e7229a5857d669ae6c
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithNoPolicies_CompletesSuccessfully::test e3f6824512503bea532826b9a9e4f7bb5abdea53f962fbbc6fdae299a6fe44a0
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithMultiplePolicies_CallsAllPolicies::test 4797cc1851d78364553dac59a6f9a894107fa04fb3fddfb52ed0e4fb5b4bcd1a
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithCancelledToken_ThrowsOperationCanceledException::test e4eaf9c1ee2d55a3e6c7bca634ff1af2a0e19b7560ea616984d258df46ec89fd
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithEmptyLists_DoesNotThrow::test 6ba7e22fb7425e523f301612f7d7f6aed88e7d422050a70137d93b4a8004ae50
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.ReportItemChangeAsync_WithNullLists_DoesNotThrowFromComposite::test c512c54f78c46fb4774d9b5c9c1057627592e1c25267811cddf3d687d3d1ec4d
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.AddRemovePolicy_ConcurrentAccess_DoesNotThrow::test a73a01065867d90305f491e41d9ea61bc27b80c026672ed920368877bfb0fe14
|
||||
// pending-parity-case: LibreMetaverse.Tests/CurrentOutfitFolderTests.cs::CompositeCurrentOutfitPolicyTests.CanAttach_WhileModifyingPolicies_DoesNotThrow::test 697999feeb776fae9a47cb9678c0ae0234d3b3831ce40c0e6f50fe622a5cc2b7
|
||||
// pending-parity-case: LibreMetaverse.Tests/EnvironmentManagerTests.cs::EnvironmentManagerTests.GetParcelEnvironment_UsesParcelidQueryParameter::test 5c2f2b0fa2a86955975c621b2415a92ff3da283215e669956e14bf5ee2a4c1f4
|
||||
// pending-parity-case: LibreMetaverse.Tests/EnvironmentManagerTests.cs::EnvironmentManagerTests.SetParcelEnvironment_SendsParcelidInQueryStringNotBody::test f633e2d78e4c6a0fff42917ccfe8de68e4f6133a11e7eef7f9b757c3d1622f0f
|
||||
// pending-parity-case: LibreMetaverse.Tests/EnvironmentManagerTests.cs::EnvironmentManagerTests.SetRegionEnvironment_OmitsQueryStringEntirely::test bade6e06765506ad7e500ac3e5c9f168605ce25fef86647819d285a68b39f109
|
||||
@@ -232,14 +120,6 @@
|
||||
// pending-parity-case: LibreMetaverse.Tests/MarketplaceManagerTests.cs::MarketplaceManagerTests.MarketplaceErrorEventArgs_StoresMessageAndException::test cb0213208ab6b63f32a950f1771354fae4b6904c72720b1705ddf5b8355ffc7d
|
||||
// pending-parity-case: LibreMetaverse.Tests/MarketplaceManagerTests.cs::MarketplaceManagerTests.MarketplaceErrorEventArgs_WithoutException_HasNullException::test de7c8addfb291cba5dee890a98ac8b5f27b192d0b75894c4102303a49785de47
|
||||
// pending-parity-case: LibreMetaverse.Tests/MarketplaceManagerTests.cs::MarketplaceManagerTests.MarketplaceListing_DefaultValues_AreCorrect::test 70a29163581702fdc32c54a398ad4cefa608da8b1bc9d54a4e9e191e95398fb7
|
||||
// pending-parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.IsLink_TextureItemWithLinkAssetType_ReturnsTrue::test b85452466c0fdc47a44cc08166f93a660bbf466b0e2205910c1ea84fee22896c
|
||||
// pending-parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.IsLink_NormalTexture_ReturnsFalse::test 8c08505d6e89c4395115dbb060529419755aa1a81ca8889804ea00e6f94bf534
|
||||
// pending-parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.ResolvedItemID_OnMisclassifiedTextureLink_ReturnsAssetUUID::test cad5b5fb10523254ff19b7842b0e48984bc75182a26bc897f165a43770bb47f4
|
||||
// pending-parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_Contains_FindsTargetByResolvedItemID::test 3c1f8596462c3a9e229c84ea44e44728bf175e1a0e8213ae92d1b02b08320b0b
|
||||
// pending-parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_Indexer_ReturnsWearable_WhenTargetIsWearable::test c7ce0b860743cfa5225de4322c8d7bf95094296b1dd2d07fd273bbd4e81a9fcf
|
||||
// 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/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
|
||||
|
||||
142
tests/compat/tests/misclassified_link_semantics.rs
Normal file
142
tests/compat/tests/misclassified_link_semantics.rs
Normal file
@@ -0,0 +1,142 @@
|
||||
// Exact Rust translations of LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs.
|
||||
// Source SHA-256: f1e2a14f9671d6af084d72cc5280daf372985bf1b08c75e5989d9c8df0932a64
|
||||
|
||||
use libremetaverse::{
|
||||
GridClient, Inventory, InventoryAttachment, InventoryObject, InventoryTexture,
|
||||
InventoryWearable,
|
||||
};
|
||||
use libremetaverse_types::{AssetType, AttachmentPoint, UUID, WearableType};
|
||||
|
||||
fn store() -> Inventory {
|
||||
Inventory::new_with_grid_client_uuid(GridClient::new().unwrap(), UUID::random().unwrap())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn texture_link(target: UUID) -> InventoryTexture {
|
||||
let mut item = InventoryTexture::new(UUID::random().unwrap()).unwrap();
|
||||
item.base.set_asset_type(AssetType::Link);
|
||||
item.base.set_asset_uuid(target);
|
||||
item
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.IsLink_TextureItemWithLinkAssetType_ReturnsTrue::test b85452466c0fdc47a44cc08166f93a660bbf466b0e2205910c1ea84fee22896c translated
|
||||
#[test]
|
||||
fn is_link_texture_item_with_link_asset_type_returns_true() {
|
||||
let item = texture_link(UUID::random().unwrap());
|
||||
assert!(item.base.is_link().unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.IsLink_NormalTexture_ReturnsFalse::test 8c08505d6e89c4395115dbb060529419755aa1a81ca8889804ea00e6f94bf534 translated
|
||||
#[test]
|
||||
fn is_link_normal_texture_returns_false() {
|
||||
let mut item = InventoryTexture::new(UUID::random().unwrap()).unwrap();
|
||||
item.base.set_asset_type(AssetType::Texture);
|
||||
item.base.set_asset_uuid(UUID::random().unwrap());
|
||||
assert!(!item.base.is_link().unwrap());
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.ResolvedItemID_OnMisclassifiedTextureLink_ReturnsAssetUUID::test cad5b5fb10523254ff19b7842b0e48984bc75182a26bc897f165a43770bb47f4 translated
|
||||
#[test]
|
||||
fn resolved_item_id_on_misclassified_texture_link_returns_asset_uuid() {
|
||||
let target = UUID::random().unwrap();
|
||||
let item = texture_link(target);
|
||||
assert_eq!(item.base.resolved_item_id(), target);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_Contains_FindsTargetByResolvedItemID::test 3c1f8596462c3a9e229c84ea44e44728bf175e1a0e8213ae92d1b02b08320b0b translated
|
||||
#[test]
|
||||
fn inventory_store_contains_finds_target_by_resolved_item_id() {
|
||||
let store = store();
|
||||
let target_id = UUID::random().unwrap();
|
||||
let mut target = InventoryWearable::new(target_id).unwrap();
|
||||
target.set_wearable_type(WearableType::Shirt);
|
||||
target.base.set_asset_type(AssetType::Clothing);
|
||||
target.base.set_asset_uuid(UUID::random().unwrap());
|
||||
store.update_node_for(target.base.base).unwrap();
|
||||
let link = texture_link(target_id);
|
||||
assert!(
|
||||
store
|
||||
.contains_with_uuid(link.base.resolved_item_id())
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_Indexer_ReturnsWearable_WhenTargetIsWearable::test c7ce0b860743cfa5225de4322c8d7bf95094296b1dd2d07fd273bbd4e81a9fcf translated
|
||||
#[test]
|
||||
fn inventory_store_indexer_returns_wearable_when_target_is_wearable() {
|
||||
let store = store();
|
||||
let target_id = UUID::random().unwrap();
|
||||
let mut target = InventoryWearable::new(target_id).unwrap();
|
||||
target.set_wearable_type(WearableType::Shirt);
|
||||
target.base.set_asset_type(AssetType::Clothing);
|
||||
target.base.set_asset_uuid(UUID::random().unwrap());
|
||||
target.base.base.set_name("Test Shirt".into());
|
||||
store.update_node_for(target.base.base).unwrap();
|
||||
let link = texture_link(target_id);
|
||||
let resolved = store
|
||||
.get_value_or_default_with_uuid_a7c63fbe::<InventoryWearable>(link.base.resolved_item_id())
|
||||
.unwrap();
|
||||
assert!(
|
||||
resolved.is_some(),
|
||||
"target must retain its InventoryWearable type"
|
||||
);
|
||||
assert_eq!(resolved.unwrap().wearable_type(), WearableType::Shirt);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_Indexer_ReturnsAttachment_WhenTargetIsAttachment::test f58debff8f66b7b417215eb6879f96935647b66cc619fdb00e6815c9ce5e7c67 translated
|
||||
#[test]
|
||||
fn inventory_store_indexer_returns_attachment_when_target_is_attachment() {
|
||||
let store = store();
|
||||
let target_id = UUID::random().unwrap();
|
||||
let mut target = InventoryAttachment::new(target_id).unwrap();
|
||||
target.set_attachment_point(AttachmentPoint::Chest);
|
||||
target.base.set_asset_type(AssetType::Object);
|
||||
target.base.set_asset_uuid(UUID::random().unwrap());
|
||||
target.base.base.set_name("Test Attachment".into());
|
||||
store.update_node_for(target.base.base).unwrap();
|
||||
let link = texture_link(target_id);
|
||||
let resolved = store
|
||||
.get_value_or_default_with_uuid_a7c63fbe::<InventoryAttachment>(
|
||||
link.base.resolved_item_id(),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
resolved.is_some(),
|
||||
"target must retain its InventoryAttachment type"
|
||||
);
|
||||
assert_eq!(resolved.unwrap().attachment_point(), AttachmentPoint::Chest);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_Indexer_ReturnsObject_WhenTargetIsObject::test b8137c994019103977b0b85d8c148e12ae8f9051334ca487db7c88bcbe707d40 translated
|
||||
#[test]
|
||||
fn inventory_store_indexer_returns_object_when_target_is_object() {
|
||||
let store = store();
|
||||
let target_id = UUID::random().unwrap();
|
||||
let mut target = InventoryObject::new(target_id).unwrap();
|
||||
target.set_attach_point(AttachmentPoint::RightHand);
|
||||
target.base.set_asset_type(AssetType::Object);
|
||||
target.base.set_asset_uuid(UUID::random().unwrap());
|
||||
target.base.base.set_name("Test Object".into());
|
||||
store.update_node_for(target.base.base).unwrap();
|
||||
let link = texture_link(target_id);
|
||||
let resolved = store
|
||||
.get_value_or_default_with_uuid_a7c63fbe::<InventoryObject>(link.base.resolved_item_id())
|
||||
.unwrap();
|
||||
assert!(
|
||||
resolved.is_some(),
|
||||
"target must retain its InventoryObject type"
|
||||
);
|
||||
assert_eq!(resolved.unwrap().attach_point(), AttachmentPoint::RightHand);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_NotContains_WhenTargetAbsent::test 6900e220c33ec135d02c55e047c7052a095d5dd9d71da4a857ae70bc151c472b translated
|
||||
#[test]
|
||||
fn inventory_store_not_contains_when_target_absent() {
|
||||
let store = store();
|
||||
let link = texture_link(UUID::random().unwrap());
|
||||
assert!(
|
||||
!store
|
||||
.contains_with_uuid(link.base.resolved_item_id())
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
use libremetaverse::http::DownloadManager;
|
||||
use libremetaverse::packets::PacketType;
|
||||
use libremetaverse::{GridClient, GridLayerType, HttpCapsClient, NetworkManager};
|
||||
use libremetaverse_compat_tests::block_on;
|
||||
use libremetaverse_compat_tests::{block_on, live_grid_credentials};
|
||||
use libremetaverse_types::compat::{
|
||||
CancellationToken, CancellationTokenSource, HttpMessageHandler, HttpRequest, HttpResponse, Uri,
|
||||
};
|
||||
@@ -158,35 +158,8 @@ where
|
||||
.await
|
||||
}
|
||||
|
||||
fn credential(name: &str) -> String {
|
||||
if let Ok(value) = std::env::var(name)
|
||||
&& !value.trim().is_empty()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
let dotenv = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../..")
|
||||
.join(".env");
|
||||
let contents = std::fs::read_to_string(dotenv).expect("read workspace .env");
|
||||
contents
|
||||
.lines()
|
||||
.find_map(|line| {
|
||||
let line = line.trim().strip_prefix("export ").unwrap_or(line.trim());
|
||||
let (key, value) = line.split_once('=')?;
|
||||
(key.trim() == name).then(|| value.trim().trim_matches(['\'', '"']).to_owned())
|
||||
})
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or_else(|| panic!("live test requires {name}"))
|
||||
}
|
||||
|
||||
fn live_credentials() -> (String, String, String, String) {
|
||||
let full_name = credential("GRID_USER");
|
||||
let password = credential("GRID_PASSWORD");
|
||||
let login_url = credential("GRID_LOGIN_URL");
|
||||
let mut names = full_name.split(' ');
|
||||
let first = names.next().expect("live first name").to_owned();
|
||||
let last = names.next().expect("live last name").to_owned();
|
||||
(first, last, password, login_url)
|
||||
live_grid_credentials()
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/DownloadManagerTests.cs::DownloadManagerTests.QueueDownloadAsync_SingleDownload_CompletesSuccessfully::test f8feb54d38f79624ddf1d368e0599259ff9d474c08ea0249a8f244460a1f533f translated
|
||||
|
||||
Reference in New Issue
Block a user