Files
navaltoolbox-lib/python/tests/test_rhai_scripting.py
T
Antoine Anceau f781dac828 fix: update Rhai method registration to use closures for proper dispatch
This resolves the 'Function not found' error by explicitly wrapping methods in closures, ensuring proper type handling for custom types in Rhai.
2026-02-04 12:04:15 +01:00

115 lines
3.4 KiB
Python

import pytest
from pathlib import Path
from navaltoolbox import (
Hull,
Vessel,
StabilityCalculator,
CriteriaContext,
ScriptEngine,
)
class TestRhaiScripting:
"""Tests for Rhai scripting integration."""
@pytest.fixture
def dtmb5415_vessel(self):
"""Load DTMB5415 hull and create vessel."""
stl_path = (
Path(__file__).parent.parent.parent
/ "rust"
/ "tests"
/ "data"
/ "dtmb5415.stl"
)
if not stl_path.exists():
pytest.skip("DTMB5415 STL file not found")
hull = Hull(str(stl_path))
return Vessel(hull)
def test_reproduce_imo_a749_error(self, dtmb5415_vessel):
"""
Reproduce the 'Function not found' error for IMO A749 script.
Specifically checking:
- find_max_gz
- area_under_curve
"""
# 1. Setup stability result
displacement = 8635000.0 # kg
lcg = 71.670
tcg = 0.0
vcg = 7.555
cog = (lcg, tcg, vcg)
calc = StabilityCalculator(dtmb5415_vessel, 1025.0)
# Calculate full curve 0-180
heels = list(range(0, 70, 5))
result = calc.complete_stability(displacement, cog, heels)
# 2. Create Context
ctx = CriteriaContext.from_result(
result,
vessel_name="DTMB 5415",
loading_condition="Design Load"
)
# 3. Initialize Engine
engine = ScriptEngine()
# 4. Load and run IMO A749 script
script_path = (
Path(__file__).parent.parent.parent
/ "rules"
/ "imo_a749_general.rhai"
)
if not script_path.exists():
pytest.skip(f"Script not found at {script_path}")
print(f"Running script: {script_path}")
# This is expected to fail currently
try:
result = engine.run_script_file(str(script_path), ctx)
print("Script execution successful!")
print(f"Overall Pass: {result.overall_pass}")
for crit in result.criteria:
print(f" - {crit.name}: {crit.status} ({crit.actual_value:.3f} {crit.unit})")
except ValueError as e:
pytest.fail(f"Script execution failed: {e}")
def test_minimal_reproduction(self, dtmb5415_vessel):
"""Minimal reproduction of specific function calls."""
displacement = 8635000.0
cog = (71.670, 0.0, 7.555)
calc = StabilityCalculator(dtmb5415_vessel, 1025.0)
heels = [0, 10, 20, 30, 40, 50, 60]
result = calc.complete_stability(displacement, cog, heels)
ctx = CriteriaContext.from_result(result, "Test", "Test")
engine = ScriptEngine()
# Test find_max_gz
script_max_gz = """
fn check(ctx) {
let max = ctx.find_max_gz();
print("Max GZ: " + max);
return #{ name: "Test", status: "PASS" };
}
"""
engine.run_script(script_max_gz, ctx)
# Test area_under_curve
script_area = """
fn check(ctx) {
let area = ctx.area_under_curve(0.0, 30.0);
print("Area: " + area);
return #{ name: "Test", status: "PASS" };
}
"""
engine.run_script(script_area, ctx)