unitforge 0.5.3

A library for unit and quantity consistent computations in Rust
Documentation
import pytest
from unitforge import *


def test_inverse_stress_from_stress_division():
    stress = Stress(2.0, StressUnit.Pa)
    inverse = 1 / stress
    assert isinstance(inverse, InverseStress)
    assert inverse.to(InverseStressUnit._Pa) == pytest.approx(0.5)


def test_stress_from_inverse_stress_division():
    inverse = InverseStress(0.5, InverseStressUnit._Pa)
    stress = 1 / inverse
    assert isinstance(stress, Stress)
    assert stress.to(StressUnit.Pa) == pytest.approx(2.0)


def test_stress_squared_from_force_stress_over_area():
    force = Force(2.0, ForceUnit.N)
    stress = Stress(3.0, StressUnit.Pa)
    area = Area(6.0, AreaUnit.msq)
    result = (force * stress) / area
    assert isinstance(result, StressSquared)
    assert result.to(StressSquaredUnit.Nsq_mmhc) == pytest.approx(1.0)


def test_force_stress_from_stress_squared_times_area():
    stress_squared = StressSquared(2.0, StressSquaredUnit.Nsq_mmhc)
    area = Area(3.0, AreaUnit.msq)
    result = stress_squared * area
    assert isinstance(result, ForceStress)
    assert result.to(ForceStressUnit.Nsq_msq) == pytest.approx(6.0)

def test_power_operator():
    a = Distance(2., DistanceUnit.mm)
    b = a**2
    assert b == Area(4., AreaUnit.mmsq)


def test_mod_operator():
    force = Force(5.5, ForceUnit.N)
    area = Area(2.0, AreaUnit.msq)
    result = force % area
    assert isinstance(result, Stress)
    assert result.to(StressUnit.Pa) == pytest.approx(1.5)


def test_mod_operator_with_scalar_rhs():
    distance = Distance(5.5, DistanceUnit.m)
    result = distance % 2.0
    assert isinstance(result, Distance)
    assert result.to(DistanceUnit.m) == pytest.approx(1.5)


def test_mod_operator_same_quantity_returns_float():
    lhs = Distance(5.5, DistanceUnit.m)
    rhs = Distance(2.0, DistanceUnit.m)
    result = lhs % rhs
    assert isinstance(result, float)
    assert result == pytest.approx(1.5)


def test_quantity_unsupported_rhs_object_raises_type_error():
    force = Force(1., ForceUnit.N)
    with pytest.raises(TypeError):
        _ = force + object()
    with pytest.raises(TypeError):
        _ = force - object()
    with pytest.raises(TypeError):
        _ = force * object()
    with pytest.raises(TypeError):
        _ = force / object()
    with pytest.raises(TypeError):
        _ = force % object()


def test_quantity_unsupported_relation_raises_type_error():
    force = Force(1., ForceUnit.N)
    time = Time(1., TimeUnit.s)
    with pytest.raises(TypeError):
        _ = force * time
    with pytest.raises(TypeError):
        _ = force / time
    with pytest.raises(TypeError):
        _ = force % time


def test_quantity_invalid_power_raises_type_error():
    force = Force(1., ForceUnit.N)
    with pytest.raises(TypeError):
        _ = force ** 2


def test_quantity_left_vector_multiplication():
    result = Force(1., ForceUnit.N) * Vector3.x()
    assert result[0] == Force(1., ForceUnit.N)
    assert result[1] == Force(0., ForceUnit.N)
    assert result[2] == Force(0., ForceUnit.N)


def test_quantity_left_vector_multiplication_with_quantity_vector():
    vec = Vector3(Distance(3., DistanceUnit.mm), Distance(4., DistanceUnit.mm), Distance(12., DistanceUnit.mm))
    result = Force(2., ForceUnit.N) * vec
    assert result[0].to(ForceDistanceUnit.Nm) == 0.006
    assert result[1].to(ForceDistanceUnit.Nm) == 0.008
    assert result[2].to(ForceDistanceUnit.Nm) == 0.024


def test_quantity_left_vector_multiplication_unsupported_relation_raises_type_error():
    vec = Vector3(Time(1., TimeUnit.s), Time(2., TimeUnit.s), Time(3., TimeUnit.s))
    with pytest.raises(TypeError):
        _ = Force(1., ForceUnit.N) * vec