Translate asset and material parity tests
Some checks failed
Rust API gates / api-gates (push) Has been cancelled

This commit is contained in:
2026-08-08 15:29:02 +02:00
parent 069e6366b2
commit 9eb4345750
15 changed files with 3735 additions and 3093 deletions

View File

@@ -0,0 +1,92 @@
// The upstream tests reach the internal OarFile.LoadTerrain member via reflection.
// Keep the equivalent Rust seam private to the owning crate.
// BSD-3-Clause source (see LICENSE.md): LibreMetaverse.Tests/OarFileTerrainTests.cs
// SHA-256: 19c42f7f132b97dc1667208f1e9b49df8ff6db96265c22b1c1ef5498e3c5c75d
#![allow(clippy::float_cmp)]
use crate::Error;
use crate::assets::OarFile;
use std::sync::{Arc, Mutex};
type Terrain = Vec<Vec<f32>>;
type TerrainLoaded = Box<dyn Fn(Terrain, i64, i64) + Send + Sync>;
impl OarFile {
fn load_terrain(
_file_path: &str,
_data: Vec<u8>,
_callback: TerrainLoaded,
_bytes_read: i64,
_total_bytes: i64,
) -> Result<bool, Error> {
libremetaverse_types::not_implemented(
"M:LibreMetaverse.Assets.OarFile.LoadTerrain(System.String,System.Byte[],LibreMetaverse.Assets.OarFile.TerrainLoadedCallback,System.Int64,System.Int64)",
)
}
}
fn raw_terrain(side: usize, fill: f32) -> Vec<u8> {
fill.to_le_bytes().repeat(side * side)
}
fn invoke_load_terrain(file_path: &str, data: Vec<u8>) -> (bool, Option<Terrain>) {
let captured = Arc::new(Mutex::new(None));
let callback_capture = Arc::clone(&captured);
let total_bytes = i64::try_from(data.len()).expect("terrain byte count fits i64");
let loaded = OarFile::load_terrain(
file_path,
data,
Box::new(move |terrain, _, _| {
*callback_capture.lock().expect("terrain capture") = Some(terrain);
}),
0,
total_bytes,
)
.expect("OarFile.LoadTerrain");
let terrain = captured.lock().expect("terrain capture").take();
(loaded, terrain)
}
// Fixture SHA-256: fcdd41fbadfe6a69d9687b3777692c2de82c831856fa8bcef978c3c17b0117fa
// parity-case: LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_StandardRegion_Loads256x256::test c4e3a994baf06b0106a6614e9c3efbcc27e45ff1725f5470d2db6ded1fff6014 translated
#[test]
fn load_standard_region_terrain() {
let (loaded, terrain) = invoke_load_terrain("terrains/region.r32", raw_terrain(256, 21.0));
assert!(loaded);
let terrain = terrain.expect("terrain callback");
assert_eq!(terrain.len(), 256);
assert!(terrain.iter().all(|row| row.len() == 256));
assert_eq!(terrain[0][0], 21.0);
}
// Fixture SHA-256: c07500b6f966d65dda9261e3e701fb5bb13e31239ff3a89d74c0046d0ba4ec12
// parity-case: LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_Varregion_Loads512x512::test 4820338f10acbb4987e26992d7a7957be58ab6bc548674bf18943ef312962894 translated
#[test]
fn load_varregion_terrain() {
let (loaded, terrain) = invoke_load_terrain("terrains/megaregion.f32", raw_terrain(512, 30.0));
assert!(loaded);
let terrain = terrain.expect("terrain callback");
assert_eq!(terrain.len(), 512);
assert!(terrain.iter().all(|row| row.len() == 512));
}
// Fixture SHA-256: 2dc88437e482fdaa5613df885d49c2b19bd623ecfc387a72338d2367d4b3b451
// parity-case: LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_WrongByteCount_FailsGracefully::test ff6fb4feb2773c93397d412d0ecf6aef1f3636e823dabb729a7a6cbe94d1513f translated
#[test]
fn reject_terrain_with_wrong_byte_count() {
let (loaded, terrain) =
invoke_load_terrain("terrains/broken.r32", vec![0; 256_usize * 256 * 4 + 3]);
assert!(!loaded);
assert!(terrain.is_none());
}
// Fixture SHA-256: 9b94b83334ada38b48b53f19ef2c45abc9f84fb723564671290a556f75d6fdc8
// parity-case: LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_NonSquarePostCount_FailsGracefully::test 218754e53232cd10318668c70b94ae9d7d541d09598b0490082e023e76d6045f translated
#[test]
fn reject_terrain_with_non_square_post_count() {
let (loaded, terrain) =
invoke_load_terrain("terrains/nonsquare.r32", vec![0; 257_usize * 256 * 4]);
assert!(!loaded);
assert!(terrain.is_none());
}