This resolves the 'Function not found' error by explicitly wrapping methods in closures, ensuring proper type handling for custom types in Rhai.
115 lines
3.4 KiB
Python
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)
|