use dodecet_encoder::{Dodecet, Point3D, Vector3D, Transform3D};
use std::time::{Duration, Instant};
#[cfg(test)]
mod wasm_integration_tests {
use super::*;
#[test]
fn test_dodecet_creation() {
let d = Dodecet::new(1000);
assert_eq!(d.value(), 1000);
assert_eq!(d.to_hex(), "3E8");
}
#[test]
fn test_dodecet_range() {
let min = Dodecet::new(0);
assert_eq!(min.value(), 0);
let max = Dodecet::new(4095);
assert_eq!(max.value(), 4095);
assert_eq!(max.to_hex(), "FFF");
let overflow = Dodecet::new(5000);
assert_eq!(overflow.value(), 5000 % 4096);
}
#[test]
fn test_point3d_encoding() {
let point = Point3D::new(100.0, 200.0, 300.0);
let dodecets = point.to_dodecets();
assert_eq!(dodecets.len(), 3);
assert!(dodecets[0].value() < 4096);
assert!(dodecets[1].value() < 4096);
assert!(dodecets[2].value() < 4096);
}
#[test]
fn test_vector3d_operations() {
let v1 = Vector3D::new(1.0, 2.0, 3.0);
let v2 = Vector3D::new(4.0, 5.0, 6.0);
let sum = v1.add(&v2);
assert_eq!(sum.x, 5.0);
assert_eq!(sum.y, 7.0);
assert_eq!(sum.z, 9.0);
let dot = v1.dot(&v2);
assert_eq!(dot, 32.0);
let cross = v1.cross(&v2);
assert_eq!(cross.x, -3.0);
assert_eq!(cross.y, 6.0);
assert_eq!(cross.z, -3.0);
}
#[test]
fn test_distance_calculation() {
let p1 = Point3D::new(0.0, 0.0, 0.0);
let p2 = Point3D::new(3.0, 4.0, 0.0);
let distance = p1.distance_to(&p2);
assert!((distance - 5.0).abs() < 0.001);
let p1_dodecets = p1.to_dodecets();
let p2_dodecets = p2.to_dodecets();
let p1_decoded = Point3D::from_dodecets(&p1_dodecets);
let p2_decoded = Point3D::from_dodecets(&p2_dodecets);
let encoded_distance = p1_decoded.distance_to(&p2_decoded);
assert!((encoded_distance - 5.0).abs() < 1.0); }
#[test]
fn test_transform3d_operations() {
let point = Point3D::new(1.0, 0.0, 0.0);
let transform = Transform3D::rotation_z(90.0);
let transformed = transform.apply(&point);
assert!((transformed.x - 0.0).abs() < 0.01);
assert!((transformed.y - 1.0).abs() < 0.01);
assert!((transformed.z - 0.0).abs() < 0.01);
}
#[test]
fn test_encoding_precision() {
let original = Point3D::new(256.5, 512.75, 1024.25);
let dodecets = original.to_dodecets();
let decoded = Point3D::from_dodecets(&dodecets);
let error_x = (original.x - decoded.x).abs();
let error_y = (original.y - decoded.y).abs();
let error_z = (original.z - decoded.z).abs();
assert!(error_x / original.x < 0.01);
assert!(error_y / original.y < 0.01);
assert!(error_z / original.z < 0.01);
}
#[test]
fn test_hex_round_trip() {
let d1 = Dodecet::new(1234);
let hex = d1.to_hex();
let d2 = Dodecet::from_hex(&hex).unwrap();
assert_eq!(d1.value(), d2.value());
}
#[test]
fn test_array_operations() {
let dodecets = vec![
Dodecet::new(100),
Dodecet::new(200),
Dodecet::new(300),
];
let hex_array = Dodecet::array_to_hex(&dodecets);
let decoded = Dodecet::array_from_hex(&hex_array).unwrap();
assert_eq!(dodecets.len(), decoded.len());
for (original, decoded_dodecet) in dodecets.iter().zip(decoded.iter()) {
assert_eq!(original.value(), decoded_dodecet.value());
}
}
#[test]
fn test_encoding_speed() {
let iterations = 10000;
let start = Instant::now();
for i in 0..iterations {
let d = Dodecet::new(i % 4096);
let _hex = d.to_hex();
}
let duration = start.elapsed();
let per_operation = duration.as_nanos() as f64 / iterations as f64;
assert!(per_operation < 25.0, "Encoding too slow: {}ns", per_operation);
}
#[test]
fn test_decoding_speed() {
let test_values: Vec<String> = (0..10000)
.map(|i| Dodecet::new(i % 4096).to_hex())
.collect();
let start = Instant::now();
for hex in &test_values {
let _d = Dodecet::from_hex(hex).unwrap();
}
let duration = start.elapsed();
let per_operation = duration.as_nanos() as f64 / test_values.len() as f64;
assert!(per_operation < 30.0, "Decoding too slow: {}ns", per_operation);
}
#[test]
fn test_geometric_operations_speed() {
let iterations = 10000;
let v1 = Vector3D::new(1.0, 2.0, 3.0);
let v2 = Vector3D::new(4.0, 5.0, 6.0);
let start = Instant::now();
for _ in 0..iterations {
let _sum = v1.add(&v2);
let _dot = v1.dot(&v2);
let _cross = v1.cross(&v2);
}
let duration = start.elapsed();
let per_operation = duration.as_nanos() as f64 / (iterations * 3) as f64;
assert!(per_operation < 20.0, "Vector ops too slow: {}ns", per_operation);
}
#[test]
fn test_distance_calculation_speed() {
let iterations = 10000;
let p1 = Point3D::new(0.0, 0.0, 0.0);
let p2 = Point3D::new(3.0, 4.0, 5.0);
let start = Instant::now();
for _ in 0..iterations {
let _distance = p1.distance_to(&p2);
}
let duration = start.elapsed();
let per_operation = duration.as_nanos() as f64 / iterations as f64;
assert!(per_operation < 45.0, "Distance calc too slow: {}ns", per_operation);
}
#[test]
fn test_memory_efficiency() {
let dodecets: Vec<Dodecet> = (0..100000)
.map(|i| Dodecet::new(i % 4096))
.collect();
let expected_size = 100000 * 2; let actual_size = std::mem::size_of_val(&*dodecets);
assert!(actual_size < expected_size * 4,
"Memory usage too high: {} bytes", actual_size);
}
#[test]
fn test_constraint_theory_integration() {
let point = Point3D::new(3.0, 4.0, 0.0);
let origin = Point3D::new(0.0, 0.0, 0.0);
let distance = point.distance_to(&origin);
assert!((distance - 5.0).abs() < 0.001);
let point_encoded = point.to_dodecets();
let origin_encoded = origin.to_dodecets();
let point_decoded = Point3D::from_dodecets(&point_encoded);
let origin_decoded = Point3D::from_dodecets(&origin_encoded);
let encoded_distance = point_decoded.distance_to(&origin_decoded);
assert!((encoded_distance - 5.0).abs() < 1.0);
}
#[test]
fn test_hex_array_format() {
let point = Point3D::new(100.0, 200.0, 300.0);
let dodecets = point.to_dodecets();
let hex_array = Dodecet::array_to_hex(&dodecets);
assert_eq!(hex_array.len(), 6);
assert!(hex_array.chars().all(|c| c.is_ascii_hexdigit()));
}
}
#[cfg(test)]
mod browser_simulation_tests {
use super::*;
#[test]
fn test_browser_memory_constraints() {
let max_memory = 50 * 1024 * 1024;
let mut dodecets = Vec::new();
let mut count = 0;
loop {
let new_dodecets: Vec<Dodecet> = (0..10000)
.map(|i| Dodecet::new(i % 4096))
.collect();
let new_size = std::mem::size_of_val(&*new_dodecets);
let current_size = std::mem::size_of_val(&*dodecets);
if current_size + new_size > max_memory {
break;
}
dodecets.extend(new_dodecets);
count += 10000;
if count > 1000000 {
break; }
}
assert!(count >= 500000, "Could only store {} dodecets in 50MB", count);
}
#[test]
fn test_wasm_performance_characteristics() {
let iterations = 1000;
let start = Instant::now();
for i in 0..iterations {
let d = Dodecet::new(i % 4096);
let _hex = d.to_hex();
let _json = format!("{{\"value\": {}, \"hex\": \"{}\"}}", d.value(), d.to_hex());
}
let duration_with_overhead = start.elapsed();
let start = Instant::now();
for i in 0..iterations {
let d = Dodecet::new(i % 4096);
let _hex = d.to_hex();
}
let duration_without_overhead = start.elapsed();
let overhead_ratio = duration_with_overhead.as_nanos() as f64 /
duration_without_overhead.as_nanos() as f64;
assert!(overhead_ratio < 2.0,
"WASM overhead too high: {}x", overhead_ratio);
}
}