93 lines
3.9 KiB
Rust
93 lines
3.9 KiB
Rust
// 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());
|
|
}
|