Translate Types and Utilities parity tests
Some checks failed
Rust API gates / api-gates (push) Has been cancelled
Some checks failed
Rust API gates / api-gates (push) Has been cancelled
This commit is contained in:
2174
tests/PARITY.md
2174
tests/PARITY.md
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,11 @@
|
||||
//! Shared deterministic fixtures used by translated compatibility tests.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::future::Future;
|
||||
use std::io;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::task::{Context, Poll, Wake, Waker};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Fails a not-yet-translated upstream test while retaining parity metadata.
|
||||
@@ -25,6 +27,27 @@ pub fn pending(
|
||||
)
|
||||
}
|
||||
|
||||
/// Runs one test future without choosing an async runtime for the library.
|
||||
pub fn block_on<F: Future>(future: F) -> F::Output {
|
||||
struct ThreadWake(std::thread::Thread);
|
||||
|
||||
impl Wake for ThreadWake {
|
||||
fn wake(self: Arc<Self>) {
|
||||
self.0.unpark();
|
||||
}
|
||||
}
|
||||
|
||||
let waker = Waker::from(Arc::new(ThreadWake(std::thread::current())));
|
||||
let mut context = Context::from_waker(&waker);
|
||||
let mut future = std::pin::pin!(future);
|
||||
loop {
|
||||
match future.as_mut().poll(&mut context) {
|
||||
Poll::Ready(output) => return output,
|
||||
Poll::Pending => std::thread::park(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Asserts equality within the exact absolute tolerance carried by an upstream test.
|
||||
///
|
||||
/// # Panics
|
||||
@@ -250,6 +273,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn deterministic_harness_covers_clock_network_and_bytes() {
|
||||
assert_eq!(block_on(std::future::ready(7)), 7);
|
||||
assert_close(1.001, 1.0, 0.01);
|
||||
assert_bytes_eq(&decode_hex("00 ff 2A").unwrap(), &[0, 255, 42]);
|
||||
assert!(decode_hex("é").is_err());
|
||||
|
||||
@@ -5,8 +5,11 @@ use libremetaverse::{
|
||||
ChatEventArgs, ChatType, InventoryException, InventoryItem, InventoryManager,
|
||||
TeleportEventArgs,
|
||||
};
|
||||
use libremetaverse_types::compat::{CancellationToken, EventHandler, Subscription};
|
||||
use libremetaverse_types::compat::{CancellationToken, Subscription};
|
||||
use libremetaverse_types::{AssetType, AttachmentPoint, UUID};
|
||||
use std::sync::Arc;
|
||||
|
||||
type EventHandler<T> = Arc<dyn Fn(T) + Send + Sync>;
|
||||
|
||||
fn member_id<T>(result: Result<T, libremetaverse::Error>) -> &'static str {
|
||||
result
|
||||
|
||||
@@ -5,7 +5,10 @@ use libremetaverse::{
|
||||
NetworkManagerDisconnectType, Settings, TexturePipeline, TexturePipelineSettings,
|
||||
UDPPacketBuffer,
|
||||
};
|
||||
use libremetaverse_types::compat::{CancellationToken, EventHandler, IProgress, Subscription, Uri};
|
||||
use libremetaverse_types::compat::{CancellationToken, IProgress, Subscription, Uri};
|
||||
use std::sync::Arc;
|
||||
|
||||
type EventHandler<T> = Arc<dyn Fn(T) + Send + Sync>;
|
||||
|
||||
fn member_id<T>(result: Result<T, libremetaverse::Error>) -> &'static str {
|
||||
result
|
||||
|
||||
@@ -2719,19 +2719,6 @@ fn estate_tools_tests_request_convenant_a027d2de58bc() {
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/EstateToolsTests.cs::EstateToolsTests.EstateInfo::test 68e1b204b4dfb56645bc6ad3a54146b2cc6ad865c298b70a2a55fc6cf148313f pending
|
||||
#[test]
|
||||
fn estate_tools_tests_estate_info_3bc323748179() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/EstateToolsTests.cs::EstateToolsTests.EstateInfo::test",
|
||||
"LibreMetaverse.Tests/EstateToolsTests.cs",
|
||||
176,
|
||||
"EstateToolsTests.EstateInfo",
|
||||
"[Test]",
|
||||
"68e1b204b4dfb56645bc6ad3a54146b2cc6ad865c298b70a2a55fc6cf148313f",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/ExperienceListAndRegionMessageTests.cs::ExperienceListAndRegionMessageTests.ExperienceListMessage_Deserialize_ReadsExperienceIdsKey::test aa1f7d09f6c79118ea2e60621d57bd63632085ce81bc979e42294aca53d4f0d9 pending
|
||||
#[test]
|
||||
fn experience_list_and_region_message_tests_experience_list_message_6df527312dbb() {
|
||||
@@ -5462,32 +5449,6 @@ fn network_tests_detect_objects_4781c499b3ef() {
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/NetworkTests.cs::NetworkTests.U64Receive::test 2d740467370db0bf967800a078aed0e810bc1a71eec76d62cb66ba8240601dac pending
|
||||
#[test]
|
||||
fn network_tests_u64_receive_8da31179adac() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/NetworkTests.cs::NetworkTests.U64Receive::test",
|
||||
"LibreMetaverse.Tests/NetworkTests.cs",
|
||||
139,
|
||||
"NetworkTests.U64Receive",
|
||||
"[Test]",
|
||||
"2d740467370db0bf967800a078aed0e810bc1a71eec76d62cb66ba8240601dac",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/NetworkTests.cs::NetworkTests.Teleport::test 2ccb0fbc0939177b28b2a3ae95651ac6c30bd5292abacfc5108ba927b0f6bccd pending
|
||||
#[test]
|
||||
fn network_tests_teleport_65828f9c5340() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/NetworkTests.cs::NetworkTests.Teleport::test",
|
||||
"LibreMetaverse.Tests/NetworkTests.cs",
|
||||
155,
|
||||
"NetworkTests.Teleport",
|
||||
"[Test]",
|
||||
"2ccb0fbc0939177b28b2a3ae95651ac6c30bd5292abacfc5108ba927b0f6bccd",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/NetworkTests.cs::NetworkTests.CapsQueue::test cd5af4e7d69df3e938540711877d167fe28efb9af8af7518a62b8f406e46cc18 pending
|
||||
#[test]
|
||||
fn network_tests_caps_queue_bbde71137aba() {
|
||||
@@ -5917,32 +5878,6 @@ fn packet_tests_to_bytes_multiple_db2623f4072b() {
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/PositionHelperTests.cs::PositionHelperTests.ToGlobalAndLocalPosition_RoundTrip::test 695c6a640e5353e02def9a1b4a1c1eabb37a8543c13466dff570f58d847e7772 pending
|
||||
#[test]
|
||||
fn position_helper_tests_to_global_and_local_position_round_trip_499dfd6841a4() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/PositionHelperTests.cs::PositionHelperTests.ToGlobalAndLocalPosition_RoundTrip::test",
|
||||
"LibreMetaverse.Tests/PositionHelperTests.cs",
|
||||
9,
|
||||
"PositionHelperTests.ToGlobalAndLocalPosition_RoundTrip",
|
||||
"[Test]",
|
||||
"695c6a640e5353e02def9a1b4a1c1eabb37a8543c13466dff570f58d847e7772",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/PositionHelperTests.cs::PositionHelperTests.FormatCoordinates_FormatsCorrectly::test fe4256d00dab5cc2de602b7b27442cac627a5956c4ce79c05d92de830f6fc5d2 pending
|
||||
#[test]
|
||||
fn position_helper_tests_format_coordinates_formats_correctly_252219c4f893() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/PositionHelperTests.cs::PositionHelperTests.FormatCoordinates_FormatsCorrectly::test",
|
||||
"LibreMetaverse.Tests/PositionHelperTests.cs",
|
||||
29,
|
||||
"PositionHelperTests.FormatCoordinates_FormatsCorrectly",
|
||||
"[Test]",
|
||||
"fe4256d00dab5cc2de602b7b27442cac627a5956c4ce79c05d92de830f6fc5d2",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/PrimObjectTests.cs::PrimObjectTests.PathBegin::test 5c8e14e1d08a91a4e7c3e252c932b8fe15cf6b5231cc9fe5bb7ef2ae6e2c8299 pending
|
||||
#[test]
|
||||
fn prim_object_tests_path_begin_612754fad0a1() {
|
||||
@@ -5995,19 +5930,6 @@ fn prim_object_tests_path_scale_e37a04cd76fb() {
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/PrimObjectTests.cs::PrimObjectTests.PathShear::test d49147475e55b06e219db0bdad056486c511b9582a6ae2601105a7b3c49844ad pending
|
||||
#[test]
|
||||
fn prim_object_tests_path_shear_80b89b3046e8() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/PrimObjectTests.cs::PrimObjectTests.PathShear::test",
|
||||
"LibreMetaverse.Tests/PrimObjectTests.cs",
|
||||
88,
|
||||
"PrimObjectTests.PathShear",
|
||||
"[Test]",
|
||||
"d49147475e55b06e219db0bdad056486c511b9582a6ae2601105a7b3c49844ad",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/PrimObjectTests.cs::PrimObjectTests.PathTaper::test 93a0adbc0630de3c9fbea6f8080d74ef6e3180e3813f00460bce5d52ef2f12b7 pending
|
||||
#[test]
|
||||
fn prim_object_tests_path_taper_3c824190973b() {
|
||||
@@ -14406,19 +14328,6 @@ fn rlv_restriction_manager_tests_remove_restrictions_for_objects_tr_8600b8deef21
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/ReaderWriterLockTests.cs::ReaderWriterLockTests.MultipleReadersOneWriter_ReaderConcurrencyAndWriterExclusion::test bf63804480951667455038244228f77c30454a365b496f062051f7b34e7b2618 pending
|
||||
#[test]
|
||||
fn reader_writer_lock_tests_multiple_readers_one_writer_reader_conc_ade8a15ef29f() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/ReaderWriterLockTests.cs::ReaderWriterLockTests.MultipleReadersOneWriter_ReaderConcurrencyAndWriterExclusion::test",
|
||||
"LibreMetaverse.Tests/ReaderWriterLockTests.cs",
|
||||
12,
|
||||
"ReaderWriterLockTests.MultipleReadersOneWriter_ReaderConcurrencyAndWriterExclusion",
|
||||
"[Test]",
|
||||
"bf63804480951667455038244228f77c30454a365b496f062051f7b34e7b2618",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/RegionScheduleTests.cs::RegionScheduleTests.GetRegionRestartScheduleAsync_WeeklySchedule_ParsesDaysAndTime::test 0f64aab66c6a6d807b3d2bbc46b636a85900e4f76e35d5e3dd8cd0d8b295618b pending
|
||||
#[test]
|
||||
fn region_schedule_tests_get_region_restart_schedule_async_weekly_s_6053e03675af() {
|
||||
@@ -15212,19 +15121,6 @@ fn terrain_material_override_tests_set_terrain_material_overrides_a_8c4f3c7893c2
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_HighFace_TextureID_IsPreserved::test 5f215cd1c50fa8871967653b4667f848c14ff24a3b71906e51aac13c56de1f55 pending
|
||||
#[test]
|
||||
fn texture_entry_tests_round_trip_high_face_texture_id_is_preserved_5238ccc2188c() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_HighFace_TextureID_IsPreserved::test",
|
||||
"LibreMetaverse.Tests/TextureEntryTests.cs",
|
||||
45,
|
||||
"TextureEntryTests.RoundTrip_HighFace_TextureID_IsPreserved",
|
||||
"[Test]",
|
||||
"5f215cd1c50fa8871967653b4667f848c14ff24a3b71906e51aac13c56de1f55",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TextureEntryTests.cs::TextureEntryTests.RoundTrip_HighFace_TextureID_IsPreserved::case:d3ad6116f2458248 5f215cd1c50fa8871967653b4667f848c14ff24a3b71906e51aac13c56de1f55 pending
|
||||
#[test]
|
||||
fn texture_entry_tests_round_trip_high_face_texture_id_is_preserved_c347d30187c6() {
|
||||
@@ -15355,97 +15251,6 @@ fn texture_entry_tests_round_trip_all_faces_texture_i_ds_all_preser_953d0ed895bf
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.UUIDs::test 4f95d48c474bbd824254196dd605051773c711614bf661b5aa996054b6c98967 pending
|
||||
#[test]
|
||||
fn type_tests_uui_ds_9bf21ba61003() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/TypeTests.cs::TypeTests.UUIDs::test",
|
||||
"LibreMetaverse.Tests/TypeTests.cs",
|
||||
38,
|
||||
"TypeTests.UUIDs",
|
||||
"[Test]",
|
||||
"4f95d48c474bbd824254196dd605051773c711614bf661b5aa996054b6c98967",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.Vector3ApproxEquals::test 1438175bb0c0bd8b17dd878e8fb95fb0dba82abbab71882f2ceb39ec554189d9 pending
|
||||
#[test]
|
||||
fn type_tests_vector3_approx_equals_1bab6a7c6f2c() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/TypeTests.cs::TypeTests.Vector3ApproxEquals::test",
|
||||
"LibreMetaverse.Tests/TypeTests.cs",
|
||||
72,
|
||||
"TypeTests.Vector3ApproxEquals",
|
||||
"[Test]",
|
||||
"1438175bb0c0bd8b17dd878e8fb95fb0dba82abbab71882f2ceb39ec554189d9",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.VectorCasting::test 27c0a4b8402ef66f11dca075d8c1a0f0b647ccef9c2803125dde6ca292951cd4 pending
|
||||
#[test]
|
||||
fn type_tests_vector_casting_2cc55b2c8d51() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/TypeTests.cs::TypeTests.VectorCasting::test",
|
||||
"LibreMetaverse.Tests/TypeTests.cs",
|
||||
100,
|
||||
"TypeTests.VectorCasting",
|
||||
"[Test]",
|
||||
"27c0a4b8402ef66f11dca075d8c1a0f0b647ccef9c2803125dde6ca292951cd4",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.Quaternions::test 071cf3ef6932e093c0fd09fe461a738e75af905707fce9a321b8f08dd89c09dd pending
|
||||
#[test]
|
||||
fn type_tests_quaternions_ee55bd386727() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/TypeTests.cs::TypeTests.Quaternions::test",
|
||||
"LibreMetaverse.Tests/TypeTests.cs",
|
||||
154,
|
||||
"TypeTests.Quaternions",
|
||||
"[Test]",
|
||||
"071cf3ef6932e093c0fd09fe461a738e75af905707fce9a321b8f08dd89c09dd",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.TestMatrix::test 5d5ccc8b9ea1741b013fd945e42ba7e6511322fdce51998e358d42c1736457e3 pending
|
||||
#[test]
|
||||
fn type_tests_test_matrix_726846ec4ddb() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/TypeTests.cs::TypeTests.TestMatrix::test",
|
||||
"LibreMetaverse.Tests/TypeTests.cs",
|
||||
185,
|
||||
"TypeTests.TestMatrix",
|
||||
"[Test]",
|
||||
"5d5ccc8b9ea1741b013fd945e42ba7e6511322fdce51998e358d42c1736457e3",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.VectorQuaternionMath::test 3c3cccd3bbec216e2be0e772b0912bec9faed5288da4f6bb4dff3c6f9952e113 pending
|
||||
#[test]
|
||||
fn type_tests_vector_quaternion_math_239214af3bde() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/TypeTests.cs::TypeTests.VectorQuaternionMath::test",
|
||||
"LibreMetaverse.Tests/TypeTests.cs",
|
||||
211,
|
||||
"TypeTests.VectorQuaternionMath",
|
||||
"[Test]",
|
||||
"3c3cccd3bbec216e2be0e772b0912bec9faed5288da4f6bb4dff3c6f9952e113",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.FloatsToTerseStrings::test ce34cdfe106d5dadfa82056e7aa7690d2da748c7e753b9d2a2ad682d86327def pending
|
||||
#[test]
|
||||
fn type_tests_floats_to_terse_strings_004651cda9df() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/TypeTests.cs::TypeTests.FloatsToTerseStrings::test",
|
||||
"LibreMetaverse.Tests/TypeTests.cs",
|
||||
223,
|
||||
"TypeTests.FloatsToTerseStrings",
|
||||
"[Test]",
|
||||
"ce34cdfe106d5dadfa82056e7aa7690d2da748c7e753b9d2a2ad682d86327def",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.BitUnpacking::test 741470d770a0a71853d84e26abaf927fc7dc385dedf0d7de87f63e7a22cb4dd7 pending
|
||||
#[test]
|
||||
fn type_tests_bit_unpacking_9f7b6fc4c72c() {
|
||||
@@ -15563,110 +15368,6 @@ fn upload_thumbnail_tests_upload_thumbnail_async_upload_does_not_co_912d32ae591d
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.FileHelper_SanitizeAndSafeNames::test 770d1cb751c4b8290c9443bcb4a91d17703628a157cc428c607a7d36ae0af985 pending
|
||||
#[test]
|
||||
fn util_unit_tests_file_helper_sanitize_and_safe_names_ebdc5251a383() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.FileHelper_SanitizeAndSafeNames::test",
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs",
|
||||
12,
|
||||
"UtilUnitTests.FileHelper_SanitizeAndSafeNames",
|
||||
"[Test]",
|
||||
"770d1cb751c4b8290c9443bcb4a91d17703628a157cc428c607a7d36ae0af985",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.ObservableDictionary_Events_FireOnAddRemoveAndClear::test 579412c3c839e1fe5b44cf956f8d329a15d4e05c05778b4e6e3ff9b7d2fb7607 pending
|
||||
#[test]
|
||||
fn util_unit_tests_observable_dictionary_events_fire_on_add_remove_dec21e72d9d7() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.ObservableDictionary_Events_FireOnAddRemoveAndClear::test",
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs",
|
||||
33,
|
||||
"UtilUnitTests.ObservableDictionary_Events_FireOnAddRemoveAndClear",
|
||||
"[Test]",
|
||||
"579412c3c839e1fe5b44cf956f8d329a15d4e05c05778b4e6e3ff9b7d2fb7607",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.EventSubscriptionHelper_WaitForEventAndAsync::test bab59e0caf1630edda9a2a6daecca95cd1a28f189fdde01b1b6afee4cd96d8cb pending
|
||||
#[test]
|
||||
fn util_unit_tests_event_subscription_helper_wait_for_event_and_asy_dd72b61bced8() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.EventSubscriptionHelper_WaitForEventAndAsync::test",
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs",
|
||||
62,
|
||||
"UtilUnitTests.EventSubscriptionHelper_WaitForEventAndAsync",
|
||||
"[Test]",
|
||||
"bab59e0caf1630edda9a2a6daecca95cd1a28f189fdde01b1b6afee4cd96d8cb",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.Repeat_Interval_ExecutesAndCancels::test 43250eb6d7799ca3c00e51810b3e04d9a874bfdeafd77af6f7b78f8f6c73ff77 pending
|
||||
#[test]
|
||||
fn util_unit_tests_repeat_interval_executes_and_cancels_ebf1b45b8eb9() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.Repeat_Interval_ExecutesAndCancels::test",
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs",
|
||||
118,
|
||||
"UtilUnitTests.Repeat_Interval_ExecutesAndCancels",
|
||||
"[Test]",
|
||||
"43250eb6d7799ca3c00e51810b3e04d9a874bfdeafd77af6f7b78f8f6c73ff77",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.NameValue_ParseAndToString::test f779a81d286c0028ea202bab00f8db0d1bbaea611003458918a9ec9a24207557 pending
|
||||
#[test]
|
||||
fn util_unit_tests_name_value_parse_and_to_string_d86a82c100bf() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.NameValue_ParseAndToString::test",
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs",
|
||||
141,
|
||||
"UtilUnitTests.NameValue_ParseAndToString",
|
||||
"[Test]",
|
||||
"f779a81d286c0028ea202bab00f8db0d1bbaea611003458918a9ec9a24207557",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.Helpers_SplitAndFloatToTerseString::test aa2c378f56cfd04d6d4cfa50cd3efafd2b2d479d681336d72fbb9d5ec5c363e6 pending
|
||||
#[test]
|
||||
fn util_unit_tests_helpers_split_and_float_to_terse_string_7b31c6f6d09a() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.Helpers_SplitAndFloatToTerseString::test",
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs",
|
||||
153,
|
||||
"UtilUnitTests.Helpers_SplitAndFloatToTerseString",
|
||||
"[Test]",
|
||||
"aa2c378f56cfd04d6d4cfa50cd3efafd2b2d479d681336d72fbb9d5ec5c363e6",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.DisposalHelper_SafeDisposeAndUsing::test 433ebbfeb69eeb7ceaac86c4b3637468152a1f5a9f4c12ea8d7a74e1cb0c4fec pending
|
||||
#[test]
|
||||
fn util_unit_tests_disposal_helper_safe_dispose_and_using_d9ec7904c289() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.DisposalHelper_SafeDisposeAndUsing::test",
|
||||
"LibreMetaverse.Tests/UtilUnitTests.cs",
|
||||
163,
|
||||
"UtilUnitTests.DisposalHelper_SafeDisposeAndUsing",
|
||||
"[Test]",
|
||||
"433ebbfeb69eeb7ceaac86c4b3637468152a1f5a9f4c12ea8d7a74e1cb0c4fec",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilsConversionsTests.cs::UtilsConversionsTests.StringToBytes::test 0bef42801dc2a50e132b05440424c44da54b53c853708ee2c0ec9799dbe0e8b2 pending
|
||||
#[test]
|
||||
fn utils_conversions_tests_string_to_bytes_fdacb435c54d() {
|
||||
pending(
|
||||
"LibreMetaverse.Tests/UtilsConversionsTests.cs::UtilsConversionsTests.StringToBytes::test",
|
||||
"LibreMetaverse.Tests/UtilsConversionsTests.cs",
|
||||
35,
|
||||
"UtilsConversionsTests.StringToBytes",
|
||||
"[Test]",
|
||||
"0bef42801dc2a50e132b05440424c44da54b53c853708ee2c0ec9799dbe0e8b2",
|
||||
);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeLLSDSample::test 2495e7d5c414b59962f03282c51fe1c0d5de350b51c1bdfcee9ced7c32acbe4d pending
|
||||
#[test]
|
||||
fn xml_sd_tests_deserialize_llsd_sample_665062bb9667() {
|
||||
|
||||
584
tests/compat/tests/types_utilities.rs
Normal file
584
tests/compat/tests/types_utilities.rs
Normal file
@@ -0,0 +1,584 @@
|
||||
#![allow(clippy::cast_possible_truncation, clippy::float_cmp)]
|
||||
|
||||
use libremetaverse::{
|
||||
DictionaryEventAction, DisposalHelper, EventSubscription, EventSubscriptionHelper, FileHelper,
|
||||
Helpers, NameValue, NameValueClassType, NameValueSendtoType, NameValueValueType,
|
||||
ObservableDictionary, PositionHelper, Repeat, Simulator, threading::OptimisticReaderWriterLock,
|
||||
};
|
||||
use libremetaverse_compat_tests::{assert_close, block_on};
|
||||
use libremetaverse_types::compat::{CancellationToken, Close, ExternalError, Guid, Utf16CodeUnit};
|
||||
use libremetaverse_types::{Matrix4, Quaternion, UUID, Utils, Vector3, Vector3d};
|
||||
use std::cell::Cell;
|
||||
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
|
||||
use std::sync::{Arc, Barrier, Mutex, mpsc};
|
||||
use std::time::Duration;
|
||||
|
||||
fn vector3(x: f32, y: f32, z: f32) -> Vector3 {
|
||||
Vector3::new_with_single_single_single(x, y, z).expect("Vector3 constructor")
|
||||
}
|
||||
|
||||
fn vector3d(x: f64, y: f64, z: f64) -> Vector3d {
|
||||
Vector3d::new_with_double_double_double(x, y, z).expect("Vector3d constructor")
|
||||
}
|
||||
|
||||
fn quaternion(x: f32, y: f32, z: f32, w: f32) -> Quaternion {
|
||||
Quaternion::new_with_single_single_single_single(x, y, z, w).expect("Quaternion constructor")
|
||||
}
|
||||
|
||||
fn matrix(values: [f32; 16]) -> Matrix4 {
|
||||
Matrix4::new_with_single_single_single_single_single_single_single_single_single_single_single_single_single_single_single_single(
|
||||
values[0], values[1], values[2], values[3], values[4], values[5], values[6],
|
||||
values[7], values[8], values[9], values[10], values[11], values[12], values[13],
|
||||
values[14], values[15],
|
||||
)
|
||||
.expect("Matrix4 constructor")
|
||||
}
|
||||
|
||||
fn assert_vector3(actual: &Vector3, expected: [f32; 3]) {
|
||||
assert_eq!([actual.x, actual.y, actual.z], expected);
|
||||
}
|
||||
|
||||
fn assert_vector3d(actual: &Vector3d, expected: [f64; 3]) {
|
||||
assert_eq!([actual.x, actual.y, actual.z], expected);
|
||||
}
|
||||
|
||||
fn assert_quaternion(actual: &Quaternion, expected: [f32; 4]) {
|
||||
assert_eq!([actual.x, actual.y, actual.z, actual.w], expected);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.UUIDs::test 4f95d48c474bbd824254196dd605051773c711614bf661b5aa996054b6c98967 translated
|
||||
#[test]
|
||||
fn uuids() {
|
||||
let zero = UUID::zero();
|
||||
assert_eq!(zero.get_bytes().expect("UUID bytes"), [0; 16]);
|
||||
|
||||
let with_trailing_bytes = vec![
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
||||
0x0f, 0xff, 0xff,
|
||||
];
|
||||
let exact_bytes = with_trailing_bytes[..16].to_vec();
|
||||
let a = UUID::new_with_bytes_int32(with_trailing_bytes, 0).expect("UUID byte constructor");
|
||||
let b = UUID::new_with_bytes_int32(exact_bytes.clone(), 0).expect("UUID byte constructor");
|
||||
assert!(a.equals_with_uuid(b));
|
||||
|
||||
let text = "00010203-0405-0607-0809-0a0b0c0d0e0f";
|
||||
let a = UUID::new_with_bytes_int32(exact_bytes, 0).expect("UUID byte constructor");
|
||||
let b = UUID::new_with_string(text.into()).expect("UUID string constructor");
|
||||
assert!(a.equals_with_uuid(b));
|
||||
|
||||
let a = UUID::new_with_string(text.into()).expect("UUID string constructor");
|
||||
assert_eq!(a.to_string(), text);
|
||||
let parsed = UUID::parse(text.into()).expect("UUID parse");
|
||||
let expected = UUID::new_with_string(text.into()).expect("UUID string constructor");
|
||||
assert!(parsed.equals_with_uuid(expected));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.Vector3ApproxEquals::test 1438175bb0c0bd8b17dd878e8fb95fb0dba82abbab71882f2ceb39ec554189d9 translated
|
||||
#[test]
|
||||
fn vector3_approx_equals() {
|
||||
let cases = [
|
||||
([1.0, 0.0, 0.0], [0.0, 0.0, 0.0], 0.9, false),
|
||||
([1.0, 0.0, 0.0], [0.0, 0.0, 0.0], 1.0, true),
|
||||
([-1.0, 0.0, 0.0], [1.0, 0.0, 0.0], 1.9, false),
|
||||
([-1.0, 0.0, 0.0], [1.0, 0.0, 0.0], 2.0, true),
|
||||
([0.0, -1.0, 0.0], [0.0, -1.1, 0.0], 0.09, false),
|
||||
([0.0, -1.0, 0.0], [0.0, -1.1, 0.0], 0.11, true),
|
||||
(
|
||||
[0.0, 0.0, 0.0],
|
||||
[0.0, 0.0, 0.00001],
|
||||
f32::from_bits(1),
|
||||
false,
|
||||
),
|
||||
([0.0, 0.0, 0.0], [0.0, 0.0, 0.00001], 0.0001, true),
|
||||
];
|
||||
for (left, right, tolerance, expected) in cases {
|
||||
let mut left = vector3(left[0], left[1], left[2]);
|
||||
let right = vector3(right[0], right[1], right[2]);
|
||||
assert_eq!(
|
||||
left.approx_equals(right, tolerance)
|
||||
.expect("Vector3 ApproxEquals"),
|
||||
expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.VectorCasting::test 27c0a4b8402ef66f11dca075d8c1a0f0b647ccef9c2803125dde6ca292951cd4 translated
|
||||
#[test]
|
||||
fn vector_casting() {
|
||||
for value in [
|
||||
1.0,
|
||||
1.1,
|
||||
1.01,
|
||||
1.001,
|
||||
1.0001,
|
||||
1.00001,
|
||||
1.000_001,
|
||||
1.000_000_1,
|
||||
1.000_000_01,
|
||||
] {
|
||||
let narrowed = value as f32;
|
||||
let no_precision_loss = value == f64::from(narrowed);
|
||||
|
||||
let c = Vector3::new_with_vector3d(vector3d(value, value, value))
|
||||
.expect("Vector3d to Vector3 cast");
|
||||
assert_vector3(&c, [narrowed; 3]);
|
||||
|
||||
let d = Vector3d::new_with_vector3(vector3(narrowed, narrowed, narrowed))
|
||||
.expect("Vector3 to Vector3d cast");
|
||||
if !no_precision_loss {
|
||||
assert_ne!([d.x, d.y, d.z], [value; 3]);
|
||||
}
|
||||
assert_vector3d(&d, [f64::from(narrowed); 3]);
|
||||
|
||||
let left = Vector3d::new_with_vector3(vector3(narrowed, narrowed, narrowed))
|
||||
.expect("implicit Vector3 to Vector3d cast");
|
||||
let right = vector3d(
|
||||
f64::from(narrowed),
|
||||
f64::from(narrowed),
|
||||
f64::from(narrowed),
|
||||
);
|
||||
assert!(Vector3d::eq(left, right));
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.Quaternions::test 071cf3ef6932e093c0fd09fe461a738e75af905707fce9a321b8f08dd89c09dd translated
|
||||
#[test]
|
||||
fn quaternions() {
|
||||
let a = quaternion(1.0, 0.0, 0.0, 0.0);
|
||||
let b = quaternion(1.0, 0.0, 0.0, 0.0);
|
||||
assert!(Quaternion::eq(a, b));
|
||||
|
||||
let result = Quaternion::multiply_with_quaternion_quaternion(
|
||||
quaternion(1.0, 0.0, 0.0, 0.0),
|
||||
quaternion(1.0, 0.0, 0.0, 0.0),
|
||||
)
|
||||
.expect("Quaternion multiply");
|
||||
assert_quaternion(&result, [0.0, 0.0, 0.0, -1.0]);
|
||||
|
||||
let result = Quaternion::multiply_with_quaternion_quaternion(
|
||||
quaternion(1.0, 0.0, 0.0, 0.0),
|
||||
quaternion(0.0, 1.0, 0.0, 0.0),
|
||||
)
|
||||
.expect("Quaternion multiply");
|
||||
assert_quaternion(&result, [0.0, 0.0, 1.0, 0.0]);
|
||||
|
||||
let result = Quaternion::multiply_with_quaternion_quaternion(
|
||||
quaternion(0.0, 0.0, 1.0, 0.0),
|
||||
quaternion(0.0, 1.0, 0.0, 0.0),
|
||||
)
|
||||
.expect("Quaternion multiply");
|
||||
assert_quaternion(&result, [-1.0, 0.0, 0.0, 0.0]);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.TestMatrix::test 5d5ccc8b9ea1741b013fd945e42ba7e6511322fdce51998e358d42c1736457e3 translated
|
||||
#[test]
|
||||
fn test_matrix() {
|
||||
let mut singular = matrix([
|
||||
0.0, 0.0, 74.0, 1.0, 0.0, 435.0, 0.0, 1.0, 345.0, 0.0, 34.0, 1.0, 0.0, 0.0, 0.0, 0.0,
|
||||
]);
|
||||
assert_close(
|
||||
f64::from(singular.determinant().expect("Matrix4 determinant")),
|
||||
0.0,
|
||||
0.001,
|
||||
);
|
||||
|
||||
let inverse_identity = Matrix4::inverse(Matrix4::identity()).expect("Matrix4 inverse");
|
||||
assert!(Matrix4::eq(Matrix4::identity(), inverse_identity));
|
||||
|
||||
let input = matrix([
|
||||
1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
]);
|
||||
let expected = matrix([
|
||||
0.0, 1.0, -1.0, 0.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
]);
|
||||
assert!(Matrix4::eq(
|
||||
Matrix4::inverse(input).expect("Matrix4 inverse"),
|
||||
expected
|
||||
));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.FloatsToTerseStrings::test ce34cdfe106d5dadfa82056e7aa7690d2da748c7e753b9d2a2ad682d86327def translated
|
||||
#[test]
|
||||
fn floats_to_terse_strings() {
|
||||
for (value, expected) in [(1.20, "1.2"), (24.00, "24"), (-0.59, "-.59"), (0.59, ".59")] {
|
||||
assert_eq!(
|
||||
Helpers::float_to_terse_string(value).expect("FloatToTerseString"),
|
||||
expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.FileHelper_SanitizeAndSafeNames::test 770d1cb751c4b8290c9443bcb4a91d17703628a157cc428c607a7d36ae0af985 translated
|
||||
#[test]
|
||||
fn file_helper_sanitize_and_safe_names() {
|
||||
let safe = FileHelper::safe_file_name("inva:lid/fi*le?.txt".into()).expect("safe file name");
|
||||
assert!(!safe.is_empty());
|
||||
assert!(!safe.contains(':'));
|
||||
assert!(
|
||||
!FileHelper::safe_dir_name("path|with?bad".into())
|
||||
.expect("safe directory name")
|
||||
.contains('|')
|
||||
);
|
||||
assert_eq!(
|
||||
FileHelper::sanitize(
|
||||
"abcxyz".into(),
|
||||
vec![Utf16CodeUnit('a' as u16), Utf16CodeUnit('b' as u16)],
|
||||
Some(Utf16CodeUnit('-' as u16)),
|
||||
)
|
||||
.expect("sanitize"),
|
||||
"--cxyz"
|
||||
);
|
||||
|
||||
let mut first = None;
|
||||
let mut last = None;
|
||||
assert!(FileHelper::try_parse_two_names(
|
||||
"First Last".into(),
|
||||
&mut first,
|
||||
&mut last
|
||||
));
|
||||
assert_eq!(first.as_deref(), Some("First"));
|
||||
assert_eq!(last.as_deref(), Some("Last"));
|
||||
assert!(!FileHelper::try_parse_two_names(
|
||||
" Too Many Parts Extra".into(),
|
||||
&mut first,
|
||||
&mut last
|
||||
));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.ObservableDictionary_Events_FireOnAddRemoveAndClear::test 579412c3c839e1fe5b44cf956f8d329a15d4e05c05778b4e6e3ff9b7d2fb7607 translated
|
||||
#[test]
|
||||
fn observable_dictionary_events_fire_on_add_remove_and_clear() {
|
||||
let mut dictionary = ObservableDictionary::<String, i32>::new_with_constructor()
|
||||
.expect("ObservableDictionary constructor");
|
||||
let adds = Arc::new(AtomicI32::new(0));
|
||||
let removes = Arc::new(AtomicI32::new(0));
|
||||
let changes = Arc::new(AtomicI32::new(0));
|
||||
|
||||
let add_count = Arc::clone(&adds);
|
||||
dictionary
|
||||
.add_delegate(
|
||||
DictionaryEventAction::Add,
|
||||
Arc::new(move |action, _entry| {
|
||||
if action == DictionaryEventAction::Add {
|
||||
add_count.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
}),
|
||||
)
|
||||
.expect("add callback");
|
||||
let remove_count = Arc::clone(&removes);
|
||||
dictionary
|
||||
.add_delegate(
|
||||
DictionaryEventAction::Remove,
|
||||
Arc::new(move |action, _entry| {
|
||||
if action == DictionaryEventAction::Remove {
|
||||
remove_count.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
}),
|
||||
)
|
||||
.expect("remove callback");
|
||||
let change_count = Arc::clone(&changes);
|
||||
dictionary
|
||||
.add_delegate(
|
||||
DictionaryEventAction::Change,
|
||||
Arc::new(move |action, _entry| {
|
||||
if action == DictionaryEventAction::Change {
|
||||
change_count.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
}),
|
||||
)
|
||||
.expect("change callback");
|
||||
|
||||
dictionary
|
||||
.add("one".into(), Some(1))
|
||||
.expect("dictionary add");
|
||||
assert_eq!(adds.load(Ordering::SeqCst), 1);
|
||||
dictionary.set_item(Some("one".into()), Some(2));
|
||||
assert!(adds.load(Ordering::SeqCst) >= 1);
|
||||
assert!(dictionary.remove("one".into()).expect("dictionary remove"));
|
||||
assert_eq!(removes.load(Ordering::SeqCst), 1);
|
||||
dictionary.add("a".into(), Some(1)).expect("dictionary add");
|
||||
dictionary.add("b".into(), Some(2)).expect("dictionary add");
|
||||
dictionary.clear().expect("dictionary clear");
|
||||
assert!(removes.load(Ordering::SeqCst) >= 3);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.EventSubscriptionHelper_WaitForEventAndAsync::test bab59e0caf1630edda9a2a6daecca95cd1a28f189fdde01b1b6afee4cd96d8cb translated
|
||||
#[test]
|
||||
fn event_subscription_helper_wait_for_event_and_async() {
|
||||
type UnitHandler = Arc<dyn Fn(Option<()>) + Send + Sync>;
|
||||
|
||||
let handler: Arc<Mutex<Option<UnitHandler>>> = Arc::new(Mutex::new(None));
|
||||
let subscribed_handler = Arc::clone(&handler);
|
||||
let unsubscribed_handler = Arc::clone(&handler);
|
||||
let fired_handler = Arc::clone(&handler);
|
||||
let (subscribed_tx, subscribed_rx) = mpsc::sync_channel(0);
|
||||
let fire = std::thread::spawn(move || {
|
||||
if subscribed_rx.recv_timeout(Duration::from_secs(5)).is_ok()
|
||||
&& let Some(handler) = fired_handler.lock().expect("event handler").as_ref()
|
||||
{
|
||||
handler(Some(()));
|
||||
}
|
||||
});
|
||||
let result =
|
||||
EventSubscriptionHelper::wait_for_event_with_action_action_func_func_int32_t_result::<
|
||||
(),
|
||||
i32,
|
||||
>(
|
||||
Box::new(move |handler| {
|
||||
*subscribed_handler.lock().expect("event handler") = Some(handler);
|
||||
subscribed_tx.send(()).expect("subscription signal");
|
||||
}),
|
||||
Box::new(move |_handler| {
|
||||
*unsubscribed_handler.lock().expect("event handler") = None;
|
||||
}),
|
||||
Box::new(|_event| true),
|
||||
Box::new(|_event| Some(123)),
|
||||
5_000,
|
||||
Some(-1),
|
||||
)
|
||||
.expect("WaitForEvent");
|
||||
assert_eq!(result, Some(123));
|
||||
fire.join().expect("event fire task");
|
||||
|
||||
let handler: Arc<Mutex<Option<UnitHandler>>> = Arc::new(Mutex::new(None));
|
||||
let subscribed_handler = Arc::clone(&handler);
|
||||
let unsubscribed_handler = Arc::clone(&handler);
|
||||
let fired_handler = Arc::clone(&handler);
|
||||
let (subscribed_tx, subscribed_rx) = mpsc::sync_channel(0);
|
||||
let fire = std::thread::spawn(move || {
|
||||
if subscribed_rx.recv_timeout(Duration::from_secs(5)).is_ok()
|
||||
&& let Some(handler) = fired_handler.lock().expect("event handler").as_ref()
|
||||
{
|
||||
handler(Some(()));
|
||||
}
|
||||
});
|
||||
let async_result = block_on(
|
||||
EventSubscriptionHelper::wait_for_event_with_action_action_func_func_int32_cancellation_token_t_result::<(), Guid>(
|
||||
Box::new(move |handler| {
|
||||
*subscribed_handler.lock().expect("event handler") = Some(handler);
|
||||
subscribed_tx.send(()).expect("subscription signal");
|
||||
}),
|
||||
Box::new(move |_handler| {
|
||||
*unsubscribed_handler.lock().expect("event handler") = None;
|
||||
}),
|
||||
Box::new(|_event| true),
|
||||
Box::new(|_event| Some(Guid([0; 16]))),
|
||||
5_000,
|
||||
Some(CancellationToken),
|
||||
Some(Guid([1; 16])),
|
||||
),
|
||||
)
|
||||
.expect("WaitForEventAsync");
|
||||
assert_eq!(async_result, Some(Guid([0; 16])));
|
||||
fire.join().expect("async event fire task");
|
||||
|
||||
let subscription = EventSubscription::<()>::new(
|
||||
Box::new(|_handler| {}),
|
||||
Box::new(|_handler| {}),
|
||||
Arc::new(|_event| {}),
|
||||
)
|
||||
.expect("EventSubscription constructor");
|
||||
subscription.dispose().expect("EventSubscription dispose");
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.Repeat_Interval_ExecutesAndCancels::test 43250eb6d7799ca3c00e51810b3e04d9a874bfdeafd77af6f7b78f8f6c73ff77 translated
|
||||
#[test]
|
||||
fn repeat_interval_executes_and_cancels() {
|
||||
let count = Arc::new(AtomicI32::new(0));
|
||||
let action_count = Arc::clone(&count);
|
||||
block_on(
|
||||
Repeat::interval_with_time_span_action_cancellation_token_boolean(
|
||||
Duration::from_millis(50),
|
||||
Box::new(move || {
|
||||
action_count.fetch_add(1, Ordering::SeqCst);
|
||||
}),
|
||||
CancellationToken,
|
||||
Some(true),
|
||||
),
|
||||
)
|
||||
.expect("Repeat interval");
|
||||
assert!(count.load(Ordering::SeqCst) >= 1);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.NameValue_ParseAndToString::test f779a81d286c0028ea202bab00f8db0d1bbaea611003458918a9ec9a24207557 translated
|
||||
#[test]
|
||||
fn name_value_parse_and_to_string() {
|
||||
let parsed =
|
||||
NameValue::new_with_string("greeting STRING R S Hello".into()).expect("NameValue parse");
|
||||
assert_eq!(parsed.name, "greeting");
|
||||
assert_eq!(parsed.type_, NameValueValueType::String);
|
||||
assert_eq!(parsed.class_, NameValueClassType::ReadOnly);
|
||||
assert_eq!(parsed.sendto, NameValueSendtoType::Sim);
|
||||
let rendered = NameValue::name_values_to_string(vec![parsed]).expect("NameValue render");
|
||||
assert!(rendered.contains("Hello"));
|
||||
|
||||
let value = NameValue::new_with_string("n1 STRING R S v1".into()).expect("NameValue parse");
|
||||
let rendered = NameValue::name_values_to_string(vec![value]).expect("NameValue render");
|
||||
assert!(rendered.contains("n1") && rendered.contains("v1"));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.Helpers_SplitAndFloatToTerseString::test aa2c378f56cfd04d6d4cfa50cd3efafd2b2d479d681336d72fbb9d5ec5c363e6 translated
|
||||
#[test]
|
||||
fn helpers_split_and_float_to_terse_string() {
|
||||
let chunks: Vec<_> = Helpers::split_by("abcdef".into(), 2)
|
||||
.expect("SplitBy")
|
||||
.collect();
|
||||
assert_eq!(chunks, ["ab", "cd", "ef"]);
|
||||
assert_eq!(
|
||||
Helpers::float_to_terse_string(0.0).expect("FloatToTerseString"),
|
||||
".00"
|
||||
);
|
||||
assert!(
|
||||
Helpers::float_to_terse_string(1.2300)
|
||||
.expect("FloatToTerseString")
|
||||
.contains("1.23")
|
||||
);
|
||||
}
|
||||
|
||||
struct ThrowOnDrop(Arc<AtomicBool>);
|
||||
|
||||
impl Close for ThrowOnDrop {}
|
||||
|
||||
impl Drop for ThrowOnDrop {
|
||||
fn drop(&mut self) {
|
||||
self.0.store(true, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
struct DisposableFlag(Cell<i32>);
|
||||
|
||||
impl Close for DisposableFlag {}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.DisposalHelper_SafeDisposeAndUsing::test 433ebbfeb69eeb7ceaac86c4b3637468152a1f5a9f4c12ea8d7a74e1cb0c4fec translated
|
||||
#[test]
|
||||
fn disposal_helper_safe_dispose_and_using() {
|
||||
let disposed = Arc::new(AtomicBool::new(false));
|
||||
let logged = Arc::new(Mutex::new(None));
|
||||
let logger_result = Arc::clone(&logged);
|
||||
DisposalHelper::safe_dispose(
|
||||
Box::new(ThrowOnDrop(Arc::clone(&disposed))),
|
||||
Some("test".into()),
|
||||
Some(Box::new(
|
||||
move |message: String, _error: Option<ExternalError>| {
|
||||
*logger_result.lock().expect("logger state") = Some(message);
|
||||
},
|
||||
)),
|
||||
)
|
||||
.expect("SafeDispose");
|
||||
assert!(disposed.load(Ordering::SeqCst));
|
||||
assert!(logged.lock().expect("logger state").is_some());
|
||||
|
||||
let result = DisposalHelper::using_with_func_func_3fbb9598(
|
||||
Box::new(|| DisposableFlag(Cell::new(0))),
|
||||
Box::new(|value| {
|
||||
value.0.set(5);
|
||||
Some(value.0.get())
|
||||
}),
|
||||
)
|
||||
.expect("Using");
|
||||
assert_eq!(result, Some(5));
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/PositionHelperTests.cs::PositionHelperTests.ToGlobalAndLocalPosition_RoundTrip::test 695c6a640e5353e02def9a1b4a1c1eabb37a8543c13466dff570f58d847e7772 translated
|
||||
#[test]
|
||||
fn to_global_and_local_position_round_trip() {
|
||||
let global_x = 512 * Simulator::DEFAULT_REGION_SIZE_X;
|
||||
let global_y = 1024 * Simulator::DEFAULT_REGION_SIZE_Y;
|
||||
let handle = Utils::u_ints_to_long(global_x, global_y).expect("region handle");
|
||||
let local = vector3(10.5, 20.25, 5.0);
|
||||
let global = PositionHelper::to_global_position(handle, local).expect("global position");
|
||||
assert_close(global.x, f64::from(global_x) + 10.5, 0.0001);
|
||||
assert_close(global.y, f64::from(global_y) + 20.25, 0.0001);
|
||||
assert_close(global.z, 5.0, 0.0001);
|
||||
let local = PositionHelper::to_local_position(handle, global).expect("local position");
|
||||
assert_close(f64::from(local.x), 10.5, 0.0001);
|
||||
assert_close(f64::from(local.y), 20.25, 0.0001);
|
||||
assert_close(f64::from(local.z), 5.0, 0.0001);
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/PositionHelperTests.cs::PositionHelperTests.FormatCoordinates_FormatsCorrectly::test fe4256d00dab5cc2de602b7b27442cac627a5956c4ce79c05d92de830f6fc5d2 translated
|
||||
#[test]
|
||||
fn format_coordinates_formats_correctly() {
|
||||
for (coordinates, expected) in [
|
||||
((None, None, None), ""),
|
||||
((Some(Some(10)), None, None), " (10)"),
|
||||
((Some(Some(10)), Some(Some(20)), None), " (10,20)"),
|
||||
(
|
||||
(Some(Some(10)), Some(Some(20)), Some(Some(30))),
|
||||
" (10,20,30)",
|
||||
),
|
||||
] {
|
||||
assert_eq!(
|
||||
PositionHelper::format_coordinates(coordinates.0, coordinates.1, coordinates.2)
|
||||
.expect("FormatCoordinates"),
|
||||
expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/ReaderWriterLockTests.cs::ReaderWriterLockTests.MultipleReadersOneWriter_ReaderConcurrencyAndWriterExclusion::test bf63804480951667455038244228f77c30454a365b496f062051f7b34e7b2618 translated
|
||||
#[test]
|
||||
fn multiple_readers_one_writer_reader_concurrency_and_writer_exclusion() {
|
||||
const READERS: usize = 5;
|
||||
let lock = Arc::new(OptimisticReaderWriterLock::new().expect("reader/writer lock constructor"));
|
||||
let start = Arc::new(Barrier::new(READERS + 1));
|
||||
let release = Arc::new(Barrier::new(READERS + 1));
|
||||
let current = Arc::new(AtomicI32::new(0));
|
||||
let maximum = Arc::new(AtomicI32::new(0));
|
||||
let (entered_tx, entered_rx) = mpsc::channel();
|
||||
let mut readers = Vec::new();
|
||||
|
||||
for _ in 0..READERS {
|
||||
let lock = Arc::clone(&lock);
|
||||
let start = Arc::clone(&start);
|
||||
let release = Arc::clone(&release);
|
||||
let current = Arc::clone(¤t);
|
||||
let maximum = Arc::clone(&maximum);
|
||||
let entered = entered_tx.clone();
|
||||
readers.push(std::thread::spawn(move || {
|
||||
start.wait();
|
||||
let _guard = lock.read_lock().expect("read lock");
|
||||
let active = current.fetch_add(1, Ordering::SeqCst) + 1;
|
||||
maximum.fetch_max(active, Ordering::SeqCst);
|
||||
entered.send(()).expect("reader entered signal");
|
||||
release.wait();
|
||||
std::thread::sleep(Duration::from_millis(20));
|
||||
current.fetch_sub(1, Ordering::SeqCst);
|
||||
}));
|
||||
}
|
||||
|
||||
start.wait();
|
||||
for _ in 0..READERS {
|
||||
entered_rx
|
||||
.recv_timeout(Duration::from_secs(30))
|
||||
.expect("all readers should enter within 30 seconds");
|
||||
}
|
||||
|
||||
let (writer_tx, writer_rx) = mpsc::channel();
|
||||
let writer_lock = Arc::clone(&lock);
|
||||
let writer = std::thread::spawn(move || {
|
||||
let _guard = writer_lock.write_lock().expect("write lock");
|
||||
writer_tx.send(()).expect("writer acquired signal");
|
||||
});
|
||||
assert!(writer_rx.recv_timeout(Duration::from_millis(100)).is_err());
|
||||
release.wait();
|
||||
writer_rx
|
||||
.recv_timeout(Duration::from_secs(30))
|
||||
.expect("writer should acquire after readers exit");
|
||||
assert!(maximum.load(Ordering::SeqCst) >= 2);
|
||||
for reader in readers {
|
||||
reader.join().expect("reader task");
|
||||
}
|
||||
writer.join().expect("writer task");
|
||||
}
|
||||
|
||||
// parity-case: LibreMetaverse.Tests/UtilsConversionsTests.cs::UtilsConversionsTests.StringToBytes::test 0bef42801dc2a50e132b05440424c44da54b53c853708ee2c0ec9799dbe0e8b2 translated
|
||||
#[test]
|
||||
fn string_to_bytes() {
|
||||
let text = "Your squirrel, your imagination";
|
||||
let bytes = Utils::string_to_bytes(text.into()).expect("StringToBytes");
|
||||
assert_eq!(
|
||||
Utils::bytes_to_string_with_bytes(bytes).expect("BytesToString"),
|
||||
text
|
||||
);
|
||||
}
|
||||
@@ -5,9 +5,10 @@ use libremetaverse::{
|
||||
TerrainManager, TerrainPatch,
|
||||
};
|
||||
use libremetaverse_types::UUID;
|
||||
use libremetaverse_types::compat::{
|
||||
CancellationToken, EventHandler, IAsyncEnumerable, Subscription,
|
||||
};
|
||||
use libremetaverse_types::compat::{CancellationToken, IAsyncEnumerable, Subscription};
|
||||
use std::sync::Arc;
|
||||
|
||||
type EventHandler<T> = Arc<dyn Fn(T) + Send + Sync>;
|
||||
|
||||
fn member_id<T>(result: Result<T, libremetaverse::Error>) -> &'static str {
|
||||
result
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user