diff --git a/tests/test_base.py b/tests/test_base.py index 4c818aba..62b37843 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -7,18 +7,27 @@ from vector import ( Abstract1DVector, + Abstract1DVectorDifferential, Abstract2DVector, + Abstract2DVectorDifferential, Abstract3DVector, + Abstract3DVectorDifferential, AbstractVector, + AbstractVectorDifferential, Cartesian1DVector, Cartesian2DVector, Cartesian3DVector, + CartesianDifferential1D, + CartesianDifferential2D, + CartesianDifferential3D, + CylindricalDifferential, CylindricalVector, IrreversibleDimensionChange, - # LnPolarVector, - # Log10PolarVector, + PolarDifferential, PolarVector, + RadialDifferential, RadialVector, + SphericalDifferential, SphericalVector, ) @@ -37,6 +46,21 @@ CylindricalVector, ] +BUILTIN_DIFFERENTIALS = [ + # 1D + CartesianDifferential1D, + RadialDifferential, + # 2D + CartesianDifferential2D, + PolarDifferential, + # LnPolarDifferential, + # Log10PolarDifferential, + # 3D + CartesianDifferential3D, + SphericalDifferential, + CylindricalDifferential, +] + def context_dimension_reduction( vector: AbstractVector, target: type[AbstractVector] @@ -78,13 +102,42 @@ def test_represent_as(self, vector, target): assert isinstance(newvec, target) -class Abstract1DVectorTest(AbstractVectorTest): - """Test :class:`vector.Abstract1DVector`.""" +class AbstractVectorDifferentialTest: + """Test :class:`vector.AbstractVectorDifferential`.""" + + @pytest.fixture(scope="class") + def vector(self) -> AbstractVector: # noqa: PT004 + """Return a vector.""" + raise NotImplementedError + + @pytest.fixture(scope="class") + def difntl(self) -> AbstractVectorDifferential: # noqa: PT004 + """Return a vector.""" + raise NotImplementedError + @pytest.mark.parametrize("target", BUILTIN_DIFFERENTIALS) + @pytest.mark.filterwarnings("ignore:Explicitly requested dtype") + def test_represent_as(self, difntl, target, vector): + """Test :meth:`AbstractVector.represent_as`. -class Abstract2DVectorTest(AbstractVectorTest): - """Test :class:`vector.Abstract2DVector`.""" + This just tests that the machiner works. + """ + # TODO: have all the convertsions + if ( + isinstance(difntl, Abstract1DVectorDifferential) + and issubclass( + target, Abstract2DVectorDifferential | Abstract3DVectorDifferential + ) + ) or ( + isinstance(difntl, Abstract2DVectorDifferential) + and issubclass(target, Abstract3DVectorDifferential) + ): + pytest.xfail("Not implemented yet") + # Perform the conversion. + # Detecting whether the conversion reduces the dimensionality. + with context_dimension_reduction(vector, target.vector_cls): + newdif = difntl.represent_as(target, vector) -class Abstract3DVectorTest(AbstractVectorTest): - """Test :class:`vector.Abstract3DVector`.""" + # Test + assert isinstance(newdif, target) diff --git a/tests/test_builtin.py b/tests/test_builtin.py deleted file mode 100644 index f98e4d63..00000000 --- a/tests/test_builtin.py +++ /dev/null @@ -1,664 +0,0 @@ -"""Test :mod:`vector._builtin`.""" - -import contextlib -from contextlib import AbstractContextManager - -import astropy.units as u -import pytest -from jax_quantity import Quantity - -from vector import ( - Abstract1DVector, - Abstract2DVector, - Abstract3DVector, - AbstractVector, - Cartesian1DVector, - Cartesian2DVector, - Cartesian3DVector, - CylindricalVector, - IrreversibleDimensionChange, - # LnPolarVector, - # Log10PolarVector, - PolarVector, - RadialVector, - SphericalVector, -) - -from .test_base import Abstract1DVectorTest - - -def context_dimension_reduction(vector, target) -> AbstractContextManager: - context: AbstractContextManager - if ( - isinstance(vector, Abstract2DVector) and issubclass(target, Abstract1DVector) - ) or ( - isinstance(vector, Abstract3DVector) - and issubclass(target, Abstract2DVector | Abstract1DVector) - ): - context = pytest.warns(IrreversibleDimensionChange) - else: - context = contextlib.nullcontext() - return context - - -class TestCartesian1DVector(Abstract1DVectorTest): - """Test :class:`vector.Cartesian1DVector`.""" - - @pytest.fixture(scope="class") - def vector(self) -> AbstractVector: - """Return a vector.""" - from vector import Cartesian1DVector - - return Cartesian1DVector(x=Quantity([1, 2, 3, 4], u.kpc)) - - # ========================================================================== - # represent_as - - def test_cartesian1d_to_cartesian1d(self, vector): - """Test ``vector.represent_as(Cartesian1DVector)``.""" - newvec = vector.represent_as(Cartesian1DVector) - assert newvec is vector - - def test_cartesian1d_to_radial(self, vector): - """Test ``vector.represent_as(RadialVector)``.""" - radial = vector.represent_as(RadialVector) - - assert isinstance(radial, RadialVector) - assert radial.r == Quantity([1, 2, 3, 4], u.kpc) - - def test_cartesian1d_to_cartesian2d(self, vector): - """Test ``vector.represent_as(Cartesian2DVector)``.""" - cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) - - assert isinstance(cart2d, Cartesian2DVector) - assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart2d.y == Quantity([5, 6, 7, 8], u.km) - - def test_cartesian1d_to_polar(self, vector): - """Test ``vector.represent_as(PolarVector)``.""" - polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) - - assert isinstance(polar, PolarVector) - assert polar.r == Quantity([1, 2, 3, 4], u.kpc) - assert polar.phi == Quantity([0, 1, 2, 3], u.rad) - - # def test_cartesian1d_to_lnpolar(self, vector): - # """Test ``vector.represent_as(LnPolarVector)``.""" - # lnpolar = vector.to_lnpolar(phi=Quantity([0, 1, 2, 3], u.rad)) - - # assert isinstance(lnpolar, LnPolarVector) - # assert lnpolar.lnr == xp.log(Quantity([1, 2, 3, 4], u.kpc)) - # assert lnpolar.phi == Quantity([0, 1, 2, 3], u.rad) - - # def test_cartesian1d_to_log10polar(self, vector): - # """Test ``vector.represent_as(Log10PolarVector)``.""" - # log10polar = vector.to_log10polar(phi=Quantity([0, 1, 2, 3], u.rad)) - - # assert isinstance(log10polar, Log10PolarVector) - # assert log10polar.log10r == xp.log10(Quantity([1, 2, 3, 4], u.kpc)) - # assert log10polar.phi == Quantity([0, 1, 2, 3], u.rad) - - def test_cartesian1d_to_cartesian3d(self, vector): - """Test ``vector.represent_as(Cartesian3DVector)``.""" - cart3d = vector.represent_as( - Cartesian3DVector, - y=Quantity([5, 6, 7, 8], u.km), - z=Quantity([9, 10, 11, 12], u.m), - ) - - assert isinstance(cart3d, Cartesian3DVector) - assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart3d.y == Quantity([5, 6, 7, 8], u.km) - assert cart3d.z == Quantity([9, 10, 11, 12], u.m) - - def test_cartesian1d_to_spherical(self, vector): - """Test ``vector.represent_as(SphericalVector)``.""" - spherical = vector.represent_as( - SphericalVector, - phi=Quantity([0, 1, 2, 3], u.rad), - theta=Quantity([4, 5, 6, 7], u.rad), - ) - - assert isinstance(spherical, SphericalVector) - assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) - assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) - assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) - - def test_cartesian1d_to_cylindrical(self, vector): - """Test ``vector.represent_as(CylindricalVector)``.""" - cylindrical = vector.represent_as( - CylindricalVector, - phi=Quantity([0, 1, 2, 3], u.rad), - z=Quantity([4, 5, 6, 7], u.m), - ) - - assert isinstance(cylindrical, CylindricalVector) - assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) - assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) - assert cylindrical.z == Quantity([4, 5, 6, 7], u.m) - - -class TestRadialVector(Abstract1DVectorTest): - """Test :class:`vector.RadialVector`.""" - - @pytest.fixture(scope="class") - def vector(self) -> AbstractVector: - """Return a vector.""" - from vector import RadialVector - - return RadialVector(r=Quantity([1, 2, 3, 4], u.kpc)) - - # ========================================================================== - # represent_as - - def test_radial_to_cartesian1d(self, vector): - """Test ``vector.represent_as(Cartesian1DVector)``.""" - cart1d = vector.represent_as(Cartesian1DVector) - - assert isinstance(cart1d, Cartesian1DVector) - assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) - - def test_radial_to_radial(self, vector): - """Test ``vector.represent_as(RadialVector)``.""" - newvec = vector.represent_as(RadialVector) - assert newvec is vector - - def test_radial_to_cartesian2d(self, vector): - """Test ``vector.represent_as(Cartesian2DVector)``.""" - cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) - - assert isinstance(cart2d, Cartesian2DVector) - assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart2d.y == Quantity([5, 6, 7, 8], u.km) - - def test_radial_to_polar(self, vector): - """Test ``vector.represent_as(PolarVector)``.""" - polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) - - assert isinstance(polar, PolarVector) - assert polar.r == Quantity([1, 2, 3, 4], u.kpc) - assert polar.phi == Quantity([0, 1, 2, 3], u.rad) - - # def test_radial_to_lnpolar(self, vector): - # """Test ``vector.represent_as(LnPolarVector)``.""" - # assert False - - # def test_radial_to_log10polar(self, vector): - # """Test ``vector.represent_as(Log10PolarVector)``.""" - # assert False - - def test_radial_to_cartesian3d(self, vector): - """Test ``vector.represent_as(Cartesian3DVector)``.""" - cart3d = vector.represent_as( - Cartesian3DVector, - y=Quantity([5, 6, 7, 8], u.km), - z=Quantity([9, 10, 11, 12], u.m), - ) - - assert isinstance(cart3d, Cartesian3DVector) - assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart3d.y == Quantity([5, 6, 7, 8], u.km) - assert cart3d.z == Quantity([9, 10, 11, 12], u.m) - - def test_radial_to_spherical(self, vector): - """Test ``vector.represent_as(SphericalVector)``.""" - spherical = vector.represent_as( - SphericalVector, - phi=Quantity([0, 1, 2, 3], u.rad), - theta=Quantity([4, 5, 6, 7], u.rad), - ) - - assert isinstance(spherical, SphericalVector) - assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) - assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) - assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) - - def test_radial_to_cylindrical(self, vector): - """Test ``vector.represent_as(CylindricalVector)``.""" - cylindrical = vector.represent_as( - CylindricalVector, - phi=Quantity([0, 1, 2, 3], u.rad), - z=Quantity([4, 5, 6, 7], u.m), - ) - - assert isinstance(cylindrical, CylindricalVector) - assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) - assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) - assert cylindrical.z == Quantity([4, 5, 6, 7], u.m) - - -class TestCartesian2DVector: - """Test :class:`vector.Cartesian2DVector`.""" - - @pytest.fixture(scope="class") - def vector(self) -> AbstractVector: - """Return a vector.""" - from vector import Cartesian2DVector - - return Cartesian2DVector( - x=Quantity([1, 2, 3, 4], u.kpc), y=Quantity([5, 6, 7, 8], u.km) - ) - - # ========================================================================== - # represent_as - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cartesian2d_to_cartesian1d(self, vector): - """Test ``vector.represent_as(Cartesian1DVector)``.""" - cart1d = vector.represent_as(Cartesian1DVector) - - assert isinstance(cart1d, Cartesian1DVector) - assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cartesian2d_to_radial(self, vector): - """Test ``vector.represent_as(RadialVector)``.""" - radial = vector.represent_as(RadialVector) - - assert isinstance(radial, RadialVector) - assert radial.r == Quantity([1, 2, 3, 4], u.kpc) - - def test_cartesian2d_to_polar(self, vector): - """Test ``vector.represent_as(PolarVector)``.""" - polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) - - assert isinstance(polar, PolarVector) - assert polar.r == Quantity([1, 2, 3, 4], u.kpc) - assert polar.phi == Quantity([0, 1, 2, 3], u.rad) - - # def test_cartesian2d_to_lnpolar(self, vector): - # """Test ``vector.represent_as(LnPolarVector)``.""" - # assert False - - # def test_cartesian2d_to_log10polar(self, vector): - # """Test ``vector.represent_as(Log10PolarVector)``.""" - # assert False - - def test_cartesian2d_to_cartesian3d(self, vector): - """Test ``vector.represent_as(Cartesian3DVector)``.""" - cart3d = vector.represent_as( - Cartesian3DVector, z=Quantity([9, 10, 11, 12], u.m) - ) - - assert isinstance(cart3d, Cartesian3DVector) - assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart3d.y == Quantity([5, 6, 7, 8], u.km) - assert cart3d.z == Quantity([9, 10, 11, 12], u.m) - - def test_cartesian2d_to_spherical(self, vector): - """Test ``vector.represent_as(SphericalVector)``.""" - spherical = vector.represent_as( - SphericalVector, theta=Quantity([4, 5, 6, 7], u.rad) - ) - - assert isinstance(spherical, SphericalVector) - assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) - assert spherical.phi == Quantity([5, 6, 7, 8], u.rad) - assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) - - def test_cartesian2d_to_cylindrical(self, vector): - """Test ``vector.represent_as(CylindricalVector)``.""" - cylindrical = vector.represent_as( - CylindricalVector, z=Quantity([9, 10, 11, 12], u.m) - ) - - assert isinstance(cylindrical, CylindricalVector) - assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) - assert cylindrical.phi == Quantity([5, 6, 7, 8], u.rad) - assert cylindrical.z == Quantity([9, 10, 11, 12], u.m) - - -class TestPolarVector: - """Test :class:`vector.PolarVector`.""" - - @pytest.fixture(scope="class") - def vector(self) -> AbstractVector: - """Return a vector.""" - from vector import PolarVector - - return PolarVector( - r=Quantity([1, 2, 3, 4], u.kpc), phi=Quantity([0, 1, 2, 3], u.rad) - ) - - # ========================================================================== - # represent_as - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_polar_to_cartesian1d(self, vector): - """Test ``vector.represent_as(Cartesian1DVector)``.""" - cart1d = vector.represent_as(Cartesian1DVector) - - assert isinstance(cart1d, Cartesian1DVector) - assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_polar_to_radial(self, vector): - """Test ``vector.represent_as(RadialVector)``.""" - radial = vector.represent_as(RadialVector) - - assert isinstance(radial, RadialVector) - assert radial.r == Quantity([1, 2, 3, 4], u.kpc) - - def test_polar_to_cartesian2d(self, vector): - """Test ``vector.represent_as(Cartesian2DVector)``.""" - cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) - - assert isinstance(cart2d, Cartesian2DVector) - assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart2d.y == Quantity([5, 6, 7, 8], u.km) - - def test_polar_to_polar(self, vector): - """Test ``vector.represent_as(PolarVector)``.""" - newvec = vector.represent_as(PolarVector) - assert newvec is vector - - # def test_polar_to_lnpolar(self, vector): - # """Test ``vector.represent_as(LnPolarVector)``.""" - # assert False - - # def test_polar_to_log10polar(self, vector): - # """Test ``vector.represent_as(Log10PolarVector) - # assert False - - def test_polar_to_cartesian3d(self, vector): - """Test ``vector.represent_as(Cartesian3DVector)``.""" - cart3d = vector.represent_as( - Cartesian3DVector, z=Quantity([9, 10, 11, 12], u.m) - ) - - assert isinstance(cart3d, Cartesian3DVector) - assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart3d.y == Quantity([5, 6, 7, 8], u.km) - assert cart3d.z == Quantity([9, 10, 11, 12], u.m) - - def test_polar_to_spherical(self, vector): - """Test ``vector.represent_as(SphericalVector)``.""" - spherical = vector.represent_as( - SphericalVector, theta=Quantity([4, 5, 6, 7], u.rad) - ) - - assert isinstance(spherical, SphericalVector) - assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) - assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) - assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) - - def test_polar_to_cylindrical(self, vector): - """Test ``vector.represent_as(CylindricalVector)``.""" - cylindrical = vector.represent_as( - CylindricalVector, z=Quantity([9, 10, 11, 12], u.m) - ) - - assert isinstance(cylindrical, CylindricalVector) - assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) - assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) - assert cylindrical.z == Quantity([9, 10, 11, 12], u.m) - - -class TestCartesian3DVector: - """Test :class:`vector.Cartesian3DVector`.""" - - @pytest.fixture(scope="class") - def vector(self) -> AbstractVector: - """Return a vector.""" - from vector import Cartesian3DVector - - return Cartesian3DVector( - x=Quantity([1, 2, 3, 4], u.kpc), - y=Quantity([5, 6, 7, 8], u.km), - z=Quantity([9, 10, 11, 12], u.m), - ) - - # ========================================================================== - # represent_as - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cartesian3d_to_cartesian1d(self, vector): - """Test ``vector.represent_as(Cartesian1DVector)``.""" - cart1d = vector.represent_as(Cartesian1DVector) - - assert isinstance(cart1d, Cartesian1DVector) - assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cartesian3d_to_radial(self, vector): - """Test ``vector.represent_as(RadialVector)``.""" - radial = vector.represent_as(RadialVector) - - assert isinstance(radial, RadialVector) - assert radial.r == Quantity([1, 2, 3, 4], u.kpc) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cartesian3d_to_cartesian2d(self, vector): - """Test ``vector.represent_as(Cartesian2DVector)``.""" - cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) - - assert isinstance(cart2d, Cartesian2DVector) - assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart2d.y == Quantity([5, 6, 7, 8], u.km) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cartesian3d_to_polar(self, vector): - """Test ``vector.represent_as(PolarVector)``.""" - polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) - - assert isinstance(polar, PolarVector) - assert polar.r == Quantity([1, 2, 3, 4], u.kpc) - assert polar.phi == Quantity([0, 1, 2, 3], u.rad) - - # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - # def test_cartesian3d_to_lnpolar(self, vector): - # """Test ``vector.represent_as(LnPolarVector)``.""" - # assert False - - # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - # def test_cartesian3d_to_log10polar(self, vector): - # """Test ``vector.represent_as(Log10PolarVector)``.""" - # assert False - - def test_cartesian3d_to_cartesian3d(self, vector): - """Test ``vector.represent_as(Cartesian3DVector)``.""" - newvec = vector.represent_as(Cartesian3DVector) - assert newvec is vector - - def test_cartesian3d_to_spherical(self, vector): - """Test ``vector.represent_as(SphericalVector)``.""" - spherical = vector.represent_as( - SphericalVector, - phi=Quantity([0, 1, 2, 3], u.rad), - theta=Quantity([4, 5, 6, 7], u.rad), - ) - - assert isinstance(spherical, SphericalVector) - assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) - assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) - assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) - - def test_cartesian3d_to_cylindrical(self, vector): - """Test ``vector.represent_as(CylindricalVector)``.""" - cylindrical = vector.represent_as( - CylindricalVector, - phi=Quantity([0, 1, 2, 3], u.rad), - z=Quantity([4, 5, 6, 7], u.m), - ) - - assert isinstance(cylindrical, CylindricalVector) - assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) - assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) - assert cylindrical.z == Quantity([4, 5, 6, 7], u.m) - - -class TestSphericalVector: - """Test :class:`vector.SphericalVector`.""" - - @pytest.fixture(scope="class") - def vector(self) -> AbstractVector: - """Return a vector.""" - from vector import SphericalVector - - return SphericalVector( - r=Quantity([1, 2, 3, 4], u.kpc), - phi=Quantity([0, 1, 2, 3], u.rad), - theta=Quantity([4, 5, 6, 7], u.rad), - ) - - # ========================================================================== - # represent_as - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_spherical_to_cartesian1d(self, vector): - """Test ``vector.represent_as(Cartesian1DVector)``.""" - cart1d = vector.represent_as(Cartesian1DVector) - - assert isinstance(cart1d, Cartesian1DVector) - assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_spherical_to_radial(self, vector): - """Test ``vector.represent_as(RadialVector)``.""" - radial = vector.represent_as(RadialVector) - - assert isinstance(radial, RadialVector) - assert radial.r == Quantity([1, 2, 3, 4], u.kpc) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_spherical_to_cartesian2d(self, vector): - """Test ``vector.represent_as(Cartesian2DVector)``.""" - cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) - - assert isinstance(cart2d, Cartesian2DVector) - assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart2d.y == Quantity([5, 6, 7, 8], u.km) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_spherical_to_polar(self, vector): - """Test ``vector.represent_as(PolarVector)``.""" - polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) - - assert isinstance(polar, PolarVector) - assert polar.r == Quantity([1, 2, 3, 4], u.kpc) - assert polar.phi == Quantity([0, 1, 2, 3], u.rad) - - # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - # def test_spherical_to_lnpolar(self, vector): - # """Test ``vector.represent_as(LnPolarVector)``.""" - # assert False - - # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - # def test_spherical_to_log10polar(self, vector): - # """Test ``vector.represent_as(Log10PolarVector)``.""" - # assert False - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_spherical_to_cartesian3d(self, vector): - """Test ``vector.represent_as(Cartesian3DVector)``.""" - cart3d = vector.represent_as( - Cartesian3DVector, z=Quantity([9, 10, 11, 12], u.m) - ) - - assert isinstance(cart3d, Cartesian3DVector) - assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart3d.y == Quantity([5, 6, 7, 8], u.km) - assert cart3d.z == Quantity([9, 10, 11, 12], u.m) - - def test_spherical_to_spherical(self, vector): - """Test ``vector.represent_as(SphericalVector)``.""" - newvec = vector.represent_as(SphericalVector) - assert newvec is vector - - def test_spherical_to_cylindrical(self, vector): - """Test ``vector.represent_as(CylindricalVector)``.""" - cylindrical = vector.represent_as( - CylindricalVector, z=Quantity([9, 10, 11, 12], u.m) - ) - - assert isinstance(cylindrical, CylindricalVector) - assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) - assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) - assert cylindrical.z == Quantity([9, 10, 11, 12], u.m) - - -class TestCylindricalVector: - """Test :class:`vector.CylindricalVector`.""" - - @pytest.fixture(scope="class") - def vector(self) -> AbstractVector: - """Return a vector.""" - from vector import CylindricalVector - - return CylindricalVector( - rho=Quantity([1, 2, 3, 4], u.kpc), - phi=Quantity([0, 1, 2, 3], u.rad), - z=Quantity([9, 10, 11, 12], u.m), - ) - - # ========================================================================== - # represent_as - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cylindrical_to_cartesian1d(self, vector): - """Test ``vector.represent_as(Cartesian1DVector)``.""" - cart1d = vector.represent_as(Cartesian1DVector) - - assert isinstance(cart1d, Cartesian1DVector) - assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cylindrical_to_radial(self, vector): - """Test ``vector.represent_as(RadialVector)``.""" - radial = vector.represent_as(RadialVector) - - assert isinstance(radial, RadialVector) - assert radial.r == Quantity([1, 2, 3, 4], u.kpc) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cylindrical_to_cartesian2d(self, vector): - """Test ``vector.represent_as(Cartesian2DVector)``.""" - cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) - - assert isinstance(cart2d, Cartesian2DVector) - assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart2d.y == Quantity([5, 6, 7, 8], u.km) - - @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - def test_cylindrical_to_polar(self, vector): - """Test ``vector.represent_as(PolarVector)``.""" - polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) - - assert isinstance(polar, PolarVector) - assert polar.r == Quantity([1, 2, 3, 4], u.kpc) - assert polar.phi == Quantity([0, 1, 2, 3], u.rad) - - # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - # def test_cylindrical_to_lnpolar(self, vector): - # """Test ``vector.represent_as(LnPolarVector)``.""" - # assert False - - # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") - # def test_cylindrical_to_log10polar(self, vector): - # """Test ``vector.represent_as(Log10PolarVector)``.""" - # assert False - - def test_cylindrical_to_cartesian3d(self, vector): - """Test ``vector.represent_as(Cartesian3DVector)``.""" - cart3d = vector.represent_as(Cartesian3DVector, y=Quantity([5, 6, 7, 8], u.km)) - - assert isinstance(cart3d, Cartesian3DVector) - assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) - assert cart3d.y == Quantity([5, 6, 7, 8], u.km) - assert cart3d.z == Quantity([9, 10, 11, 12], u.m) - - def test_cylindrical_to_spherical(self, vector): - """Test ``vector.represent_as(SphericalVector)``.""" - spherical = vector.represent_as( - SphericalVector, theta=Quantity([4, 5, 6, 7], u.rad) - ) - - assert isinstance(spherical, SphericalVector) - assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) - assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) - assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) - - def test_cylindrical_to_cylindrical(self, vector): - """Test ``vector.represent_as(CylindricalVector)``.""" - newvec = vector.represent_as(CylindricalVector) - assert newvec is vector diff --git a/tests/test_d1.py b/tests/test_d1.py new file mode 100644 index 00000000..b1a2e98a --- /dev/null +++ b/tests/test_d1.py @@ -0,0 +1,322 @@ +"""Test :mod:`vector._d1`.""" + +import astropy.units as u +import pytest +from jax_quantity import Quantity + +from vector import ( + AbstractVector, + Cartesian1DVector, + Cartesian2DVector, + Cartesian3DVector, + CartesianDifferential1D, + CartesianDifferential2D, + CartesianDifferential3D, + CylindricalDifferential, + CylindricalVector, + PolarDifferential, + PolarVector, + RadialDifferential, + RadialVector, + SphericalDifferential, + SphericalVector, +) + +from .test_base import AbstractVectorDifferentialTest, AbstractVectorTest + + +class Abstract1DVectorTest(AbstractVectorTest): + """Test :class:`vector.Abstract1DVector`.""" + + +class TestCartesian1DVector(Abstract1DVectorTest): + """Test :class:`vector.Cartesian1DVector`.""" + + @pytest.fixture(scope="class") + def vector(self) -> AbstractVector: + """Return a vector.""" + from vector import Cartesian1DVector + + return Cartesian1DVector(x=Quantity([1, 2, 3, 4], u.kpc)) + + # ========================================================================== + # represent_as + + def test_cartesian1d_to_cartesian1d(self, vector): + """Test ``vector.represent_as(Cartesian1DVector)``.""" + newvec = vector.represent_as(Cartesian1DVector) + assert newvec is vector + + def test_cartesian1d_to_radial(self, vector): + """Test ``vector.represent_as(RadialVector)``.""" + radial = vector.represent_as(RadialVector) + + assert isinstance(radial, RadialVector) + assert radial.r == Quantity([1, 2, 3, 4], u.kpc) + + def test_cartesian1d_to_cartesian2d(self, vector): + """Test ``vector.represent_as(Cartesian2DVector)``.""" + cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) + + assert isinstance(cart2d, Cartesian2DVector) + assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart2d.y == Quantity([5, 6, 7, 8], u.km) + + def test_cartesian1d_to_polar(self, vector): + """Test ``vector.represent_as(PolarVector)``.""" + polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) + + assert isinstance(polar, PolarVector) + assert polar.r == Quantity([1, 2, 3, 4], u.kpc) + assert polar.phi == Quantity([0, 1, 2, 3], u.rad) + + # def test_cartesian1d_to_lnpolar(self, vector): + # """Test ``vector.represent_as(LnPolarVector)``.""" + # lnpolar = vector.to_lnpolar(phi=Quantity([0, 1, 2, 3], u.rad)) + + # assert isinstance(lnpolar, LnPolarVector) + # assert lnpolar.lnr == xp.log(Quantity([1, 2, 3, 4], u.kpc)) + # assert lnpolar.phi == Quantity([0, 1, 2, 3], u.rad) + + # def test_cartesian1d_to_log10polar(self, vector): + # """Test ``vector.represent_as(Log10PolarVector)``.""" + # log10polar = vector.to_log10polar(phi=Quantity([0, 1, 2, 3], u.rad)) + + # assert isinstance(log10polar, Log10PolarVector) + # assert log10polar.log10r == xp.log10(Quantity([1, 2, 3, 4], u.kpc)) + # assert log10polar.phi == Quantity([0, 1, 2, 3], u.rad) + + def test_cartesian1d_to_cartesian3d(self, vector): + """Test ``vector.represent_as(Cartesian3DVector)``.""" + cart3d = vector.represent_as( + Cartesian3DVector, + y=Quantity([5, 6, 7, 8], u.km), + z=Quantity([9, 10, 11, 12], u.m), + ) + + assert isinstance(cart3d, Cartesian3DVector) + assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart3d.y == Quantity([5, 6, 7, 8], u.km) + assert cart3d.z == Quantity([9, 10, 11, 12], u.m) + + def test_cartesian1d_to_spherical(self, vector): + """Test ``vector.represent_as(SphericalVector)``.""" + spherical = vector.represent_as( + SphericalVector, + phi=Quantity([0, 1, 2, 3], u.rad), + theta=Quantity([4, 5, 6, 7], u.rad), + ) + + assert isinstance(spherical, SphericalVector) + assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) + assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) + assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) + + def test_cartesian1d_to_cylindrical(self, vector): + """Test ``vector.represent_as(CylindricalVector)``.""" + cylindrical = vector.represent_as( + CylindricalVector, + phi=Quantity([0, 1, 2, 3], u.rad), + z=Quantity([4, 5, 6, 7], u.m), + ) + + assert isinstance(cylindrical, CylindricalVector) + assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) + assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) + assert cylindrical.z == Quantity([4, 5, 6, 7], u.m) + + +class TestRadialVector(Abstract1DVectorTest): + """Test :class:`vector.RadialVector`.""" + + @pytest.fixture(scope="class") + def vector(self) -> AbstractVector: + """Return a vector.""" + from vector import RadialVector + + return RadialVector(r=Quantity([1, 2, 3, 4], u.kpc)) + + # ========================================================================== + # represent_as + + def test_radial_to_cartesian1d(self, vector): + """Test ``vector.represent_as(Cartesian1DVector)``.""" + cart1d = vector.represent_as(Cartesian1DVector) + + assert isinstance(cart1d, Cartesian1DVector) + assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) + + def test_radial_to_radial(self, vector): + """Test ``vector.represent_as(RadialVector)``.""" + newvec = vector.represent_as(RadialVector) + assert newvec is vector + + def test_radial_to_cartesian2d(self, vector): + """Test ``vector.represent_as(Cartesian2DVector)``.""" + cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) + + assert isinstance(cart2d, Cartesian2DVector) + assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart2d.y == Quantity([5, 6, 7, 8], u.km) + + def test_radial_to_polar(self, vector): + """Test ``vector.represent_as(PolarVector)``.""" + polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) + + assert isinstance(polar, PolarVector) + assert polar.r == Quantity([1, 2, 3, 4], u.kpc) + assert polar.phi == Quantity([0, 1, 2, 3], u.rad) + + # def test_radial_to_lnpolar(self, vector): + # """Test ``vector.represent_as(LnPolarVector)``.""" + # assert False + + # def test_radial_to_log10polar(self, vector): + # """Test ``vector.represent_as(Log10PolarVector)``.""" + # assert False + + def test_radial_to_cartesian3d(self, vector): + """Test ``vector.represent_as(Cartesian3DVector)``.""" + cart3d = vector.represent_as( + Cartesian3DVector, + y=Quantity([5, 6, 7, 8], u.km), + z=Quantity([9, 10, 11, 12], u.m), + ) + + assert isinstance(cart3d, Cartesian3DVector) + assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart3d.y == Quantity([5, 6, 7, 8], u.km) + assert cart3d.z == Quantity([9, 10, 11, 12], u.m) + + def test_radial_to_spherical(self, vector): + """Test ``vector.represent_as(SphericalVector)``.""" + spherical = vector.represent_as( + SphericalVector, + phi=Quantity([0, 1, 2, 3], u.rad), + theta=Quantity([4, 5, 6, 7], u.rad), + ) + + assert isinstance(spherical, SphericalVector) + assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) + assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) + assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) + + def test_radial_to_cylindrical(self, vector): + """Test ``vector.represent_as(CylindricalVector)``.""" + cylindrical = vector.represent_as( + CylindricalVector, + phi=Quantity([0, 1, 2, 3], u.rad), + z=Quantity([4, 5, 6, 7], u.m), + ) + + assert isinstance(cylindrical, CylindricalVector) + assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) + assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) + assert cylindrical.z == Quantity([4, 5, 6, 7], u.m) + + +class AbstractDifferential1DTest(AbstractVectorDifferentialTest): + """Test :class:`vector.AbstractDifferential1D`.""" + + +class TestCartesianDifferential1D(AbstractDifferential1DTest): + """Test :class:`vector.CartesianDifferential1D`.""" + + @pytest.fixture(scope="class") + def difntl(self) -> CartesianDifferential1D: + """Return a vector.""" + return CartesianDifferential1D(d_x=Quantity([1.0, 2, 3, 4], u.kpc)) + + @pytest.fixture(scope="class") + def vector(self) -> Cartesian1DVector: + """Return a vector.""" + return Cartesian1DVector(x=Quantity([1.0, 2, 3, 4], u.kpc)) + + # ========================================================================== + # represent_as + + @pytest.mark.filterwarnings("ignore:Explicitly requested dtype") + def test_cartesian1d_to_cartesian1d(self, difntl, vector): + """Test ``difntl.represent_as(CartesianDifferential1D)``.""" + newvec = difntl.represent_as(CartesianDifferential1D, vector) + assert newvec is difntl + + @pytest.mark.filterwarnings("ignore:Explicitly requested dtype") + def test_cartesian1d_to_radial(self, difntl, vector): + """Test ``difntl.represent_as(RadialDifferential)``.""" + radial = difntl.represent_as(RadialDifferential, vector) + + assert isinstance(radial, RadialDifferential) + assert radial.d_r == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.xfail(reason="Not implemented") + @pytest.mark.filterwarnings("ignore:Explicitly requested dtype") + def test_cartesian1d_to_cartesian2d(self, difntl, vector): + """Test ``difntl.represent_as(CartesianDifferential2D)``.""" + cart2d = difntl.represent_as( + CartesianDifferential2D, vector, dy=Quantity([5, 6, 7, 8], u.km) + ) + + assert isinstance(cart2d, CartesianDifferential2D) + assert cart2d.d_x == Quantity([1, 2, 3, 4], u.kpc) + assert cart2d.d_y == Quantity([5, 6, 7, 8], u.km) + + @pytest.mark.xfail(reason="Not implemented") + @pytest.mark.filterwarnings("ignore:Explicitly requested dtype") + def test_cartesian1d_to_polar(self, difntl, vector): + """Test ``difntl.represent_as(PolarDifferential)``.""" + polar = difntl.represent_as( + PolarDifferential, vector, dphi=Quantity([0, 1, 2, 3], u.rad) + ) + + assert isinstance(polar, PolarDifferential) + assert polar.d_r == Quantity([1, 2, 3, 4], u.kpc) + assert polar.d_phi == Quantity([0, 1, 2, 3], u.rad) + + @pytest.mark.xfail(reason="Not implemented") + @pytest.mark.filterwarnings("ignore:Explicitly requested dtype") + def test_cartesian1d_to_cartesian3d(self, difntl, vector): + """Test ``difntl.represent_as(CartesianDifferential3D)``.""" + cart3d = difntl.represent_as( + CartesianDifferential3D, + vector, + dy=Quantity([5, 6, 7, 8], u.km), + dz=Quantity([9, 10, 11, 12], u.m), + ) + + assert isinstance(cart3d, CartesianDifferential3D) + assert cart3d.d_x == Quantity([1, 2, 3, 4], u.kpc) + assert cart3d.d_y == Quantity([5, 6, 7, 8], u.km) + assert cart3d.d_z == Quantity([9, 10, 11, 12], u.m) + + @pytest.mark.xfail(reason="Not implemented") + @pytest.mark.filterwarnings("ignore:Explicitly requested dtype") + def test_cartesian1d_to_spherical(self, difntl, vector): + """Test ``difntl.represent_as(SphericalDifferential)``.""" + spherical = difntl.represent_as( + SphericalDifferential, + vector, + dphi=Quantity([0, 1, 2, 3], u.rad), + dtheta=Quantity([4, 5, 6, 7], u.rad), + ) + + assert isinstance(spherical, SphericalDifferential) + assert spherical.d_r == Quantity([1, 2, 3, 4], u.kpc) + assert spherical.d_phi == Quantity([0, 1, 2, 3], u.rad) + assert spherical.dtheta == Quantity([4, 5, 6, 7], u.rad) + + @pytest.mark.xfail(reason="Not implemented") + @pytest.mark.filterwarnings("ignore:Explicitly requested dtype") + def test_cartesian1d_to_cylindrical(self, difntl, vector): + """Test ``difntl.represent_as(CylindricalDifferential)``.""" + cylindrical = difntl.represent_as( + CylindricalDifferential, + vector, + dphi=Quantity([0, 1, 2, 3], u.rad), + dz=Quantity([4, 5, 6, 7], u.m), + ) + + assert isinstance(cylindrical, CylindricalDifferential) + assert cylindrical.d_rho == Quantity([1, 2, 3, 4], u.kpc) + assert cylindrical.d_phi == Quantity([0, 1, 2, 3], u.rad) + assert cylindrical.d_z == Quantity([4, 5, 6, 7], u.m) diff --git a/tests/test_d2.py b/tests/test_d2.py new file mode 100644 index 00000000..9bf687aa --- /dev/null +++ b/tests/test_d2.py @@ -0,0 +1,189 @@ +"""Test :mod:`vector._d2`.""" + +import astropy.units as u +import pytest +from jax_quantity import Quantity + +from vector import ( + AbstractVector, + Cartesian1DVector, + Cartesian2DVector, + Cartesian3DVector, + CylindricalVector, + PolarVector, + RadialVector, + SphericalVector, +) + +from .test_base import AbstractVectorTest + + +class Abstract2DVectorTest(AbstractVectorTest): + """Test :class:`vector.Abstract2DVector`.""" + + +class TestCartesian2DVector: + """Test :class:`vector.Cartesian2DVector`.""" + + @pytest.fixture(scope="class") + def vector(self) -> AbstractVector: + """Return a vector.""" + from vector import Cartesian2DVector + + return Cartesian2DVector( + x=Quantity([1, 2, 3, 4], u.kpc), y=Quantity([5, 6, 7, 8], u.km) + ) + + # ========================================================================== + # represent_as + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cartesian2d_to_cartesian1d(self, vector): + """Test ``vector.represent_as(Cartesian1DVector)``.""" + cart1d = vector.represent_as(Cartesian1DVector) + + assert isinstance(cart1d, Cartesian1DVector) + assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cartesian2d_to_radial(self, vector): + """Test ``vector.represent_as(RadialVector)``.""" + radial = vector.represent_as(RadialVector) + + assert isinstance(radial, RadialVector) + assert radial.r == Quantity([1, 2, 3, 4], u.kpc) + + def test_cartesian2d_to_polar(self, vector): + """Test ``vector.represent_as(PolarVector)``.""" + polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) + + assert isinstance(polar, PolarVector) + assert polar.r == Quantity([1, 2, 3, 4], u.kpc) + assert polar.phi == Quantity([0, 1, 2, 3], u.rad) + + # def test_cartesian2d_to_lnpolar(self, vector): + # """Test ``vector.represent_as(LnPolarVector)``.""" + # assert False + + # def test_cartesian2d_to_log10polar(self, vector): + # """Test ``vector.represent_as(Log10PolarVector)``.""" + # assert False + + def test_cartesian2d_to_cartesian3d(self, vector): + """Test ``vector.represent_as(Cartesian3DVector)``.""" + cart3d = vector.represent_as( + Cartesian3DVector, z=Quantity([9, 10, 11, 12], u.m) + ) + + assert isinstance(cart3d, Cartesian3DVector) + assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart3d.y == Quantity([5, 6, 7, 8], u.km) + assert cart3d.z == Quantity([9, 10, 11, 12], u.m) + + def test_cartesian2d_to_spherical(self, vector): + """Test ``vector.represent_as(SphericalVector)``.""" + spherical = vector.represent_as( + SphericalVector, theta=Quantity([4, 5, 6, 7], u.rad) + ) + + assert isinstance(spherical, SphericalVector) + assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) + assert spherical.phi == Quantity([5, 6, 7, 8], u.rad) + assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) + + def test_cartesian2d_to_cylindrical(self, vector): + """Test ``vector.represent_as(CylindricalVector)``.""" + cylindrical = vector.represent_as( + CylindricalVector, z=Quantity([9, 10, 11, 12], u.m) + ) + + assert isinstance(cylindrical, CylindricalVector) + assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) + assert cylindrical.phi == Quantity([5, 6, 7, 8], u.rad) + assert cylindrical.z == Quantity([9, 10, 11, 12], u.m) + + +class TestPolarVector: + """Test :class:`vector.PolarVector`.""" + + @pytest.fixture(scope="class") + def vector(self) -> AbstractVector: + """Return a vector.""" + from vector import PolarVector + + return PolarVector( + r=Quantity([1, 2, 3, 4], u.kpc), phi=Quantity([0, 1, 2, 3], u.rad) + ) + + # ========================================================================== + # represent_as + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_polar_to_cartesian1d(self, vector): + """Test ``vector.represent_as(Cartesian1DVector)``.""" + cart1d = vector.represent_as(Cartesian1DVector) + + assert isinstance(cart1d, Cartesian1DVector) + assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_polar_to_radial(self, vector): + """Test ``vector.represent_as(RadialVector)``.""" + radial = vector.represent_as(RadialVector) + + assert isinstance(radial, RadialVector) + assert radial.r == Quantity([1, 2, 3, 4], u.kpc) + + def test_polar_to_cartesian2d(self, vector): + """Test ``vector.represent_as(Cartesian2DVector)``.""" + cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) + + assert isinstance(cart2d, Cartesian2DVector) + assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart2d.y == Quantity([5, 6, 7, 8], u.km) + + def test_polar_to_polar(self, vector): + """Test ``vector.represent_as(PolarVector)``.""" + newvec = vector.represent_as(PolarVector) + assert newvec is vector + + # def test_polar_to_lnpolar(self, vector): + # """Test ``vector.represent_as(LnPolarVector)``.""" + # assert False + + # def test_polar_to_log10polar(self, vector): + # """Test ``vector.represent_as(Log10PolarVector) + # assert False + + def test_polar_to_cartesian3d(self, vector): + """Test ``vector.represent_as(Cartesian3DVector)``.""" + cart3d = vector.represent_as( + Cartesian3DVector, z=Quantity([9, 10, 11, 12], u.m) + ) + + assert isinstance(cart3d, Cartesian3DVector) + assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart3d.y == Quantity([5, 6, 7, 8], u.km) + assert cart3d.z == Quantity([9, 10, 11, 12], u.m) + + def test_polar_to_spherical(self, vector): + """Test ``vector.represent_as(SphericalVector)``.""" + spherical = vector.represent_as( + SphericalVector, theta=Quantity([4, 5, 6, 7], u.rad) + ) + + assert isinstance(spherical, SphericalVector) + assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) + assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) + assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) + + def test_polar_to_cylindrical(self, vector): + """Test ``vector.represent_as(CylindricalVector)``.""" + cylindrical = vector.represent_as( + CylindricalVector, z=Quantity([9, 10, 11, 12], u.m) + ) + + assert isinstance(cylindrical, CylindricalVector) + assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) + assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) + assert cylindrical.z == Quantity([9, 10, 11, 12], u.m) diff --git a/tests/test_d3.py b/tests/test_d3.py new file mode 100644 index 00000000..dfbfa73b --- /dev/null +++ b/tests/test_d3.py @@ -0,0 +1,292 @@ +"""Test :mod:`vector._builtin`.""" + +import astropy.units as u +import pytest +from jax_quantity import Quantity + +from vector import ( + AbstractVector, + Cartesian1DVector, + Cartesian2DVector, + Cartesian3DVector, + CylindricalVector, + PolarVector, + RadialVector, + SphericalVector, +) + +from .test_base import AbstractVectorTest + + +class Abstract3DVectorTest(AbstractVectorTest): + """Test :class:`vector.Abstract3DVector`.""" + + +class TestCartesian3DVector: + """Test :class:`vector.Cartesian3DVector`.""" + + @pytest.fixture(scope="class") + def vector(self) -> AbstractVector: + """Return a vector.""" + from vector import Cartesian3DVector + + return Cartesian3DVector( + x=Quantity([1, 2, 3, 4], u.kpc), + y=Quantity([5, 6, 7, 8], u.km), + z=Quantity([9, 10, 11, 12], u.m), + ) + + # ========================================================================== + # represent_as + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cartesian3d_to_cartesian1d(self, vector): + """Test ``vector.represent_as(Cartesian1DVector)``.""" + cart1d = vector.represent_as(Cartesian1DVector) + + assert isinstance(cart1d, Cartesian1DVector) + assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cartesian3d_to_radial(self, vector): + """Test ``vector.represent_as(RadialVector)``.""" + radial = vector.represent_as(RadialVector) + + assert isinstance(radial, RadialVector) + assert radial.r == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cartesian3d_to_cartesian2d(self, vector): + """Test ``vector.represent_as(Cartesian2DVector)``.""" + cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) + + assert isinstance(cart2d, Cartesian2DVector) + assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart2d.y == Quantity([5, 6, 7, 8], u.km) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cartesian3d_to_polar(self, vector): + """Test ``vector.represent_as(PolarVector)``.""" + polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) + + assert isinstance(polar, PolarVector) + assert polar.r == Quantity([1, 2, 3, 4], u.kpc) + assert polar.phi == Quantity([0, 1, 2, 3], u.rad) + + # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + # def test_cartesian3d_to_lnpolar(self, vector): + # """Test ``vector.represent_as(LnPolarVector)``.""" + # assert False + + # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + # def test_cartesian3d_to_log10polar(self, vector): + # """Test ``vector.represent_as(Log10PolarVector)``.""" + # assert False + + def test_cartesian3d_to_cartesian3d(self, vector): + """Test ``vector.represent_as(Cartesian3DVector)``.""" + newvec = vector.represent_as(Cartesian3DVector) + assert newvec is vector + + def test_cartesian3d_to_spherical(self, vector): + """Test ``vector.represent_as(SphericalVector)``.""" + spherical = vector.represent_as( + SphericalVector, + phi=Quantity([0, 1, 2, 3], u.rad), + theta=Quantity([4, 5, 6, 7], u.rad), + ) + + assert isinstance(spherical, SphericalVector) + assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) + assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) + assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) + + def test_cartesian3d_to_cylindrical(self, vector): + """Test ``vector.represent_as(CylindricalVector)``.""" + cylindrical = vector.represent_as( + CylindricalVector, + phi=Quantity([0, 1, 2, 3], u.rad), + z=Quantity([4, 5, 6, 7], u.m), + ) + + assert isinstance(cylindrical, CylindricalVector) + assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) + assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) + assert cylindrical.z == Quantity([4, 5, 6, 7], u.m) + + +class TestSphericalVector: + """Test :class:`vector.SphericalVector`.""" + + @pytest.fixture(scope="class") + def vector(self) -> AbstractVector: + """Return a vector.""" + from vector import SphericalVector + + return SphericalVector( + r=Quantity([1, 2, 3, 4], u.kpc), + phi=Quantity([0, 1, 2, 3], u.rad), + theta=Quantity([4, 5, 6, 7], u.rad), + ) + + # ========================================================================== + # represent_as + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_spherical_to_cartesian1d(self, vector): + """Test ``vector.represent_as(Cartesian1DVector)``.""" + cart1d = vector.represent_as(Cartesian1DVector) + + assert isinstance(cart1d, Cartesian1DVector) + assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_spherical_to_radial(self, vector): + """Test ``vector.represent_as(RadialVector)``.""" + radial = vector.represent_as(RadialVector) + + assert isinstance(radial, RadialVector) + assert radial.r == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_spherical_to_cartesian2d(self, vector): + """Test ``vector.represent_as(Cartesian2DVector)``.""" + cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) + + assert isinstance(cart2d, Cartesian2DVector) + assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart2d.y == Quantity([5, 6, 7, 8], u.km) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_spherical_to_polar(self, vector): + """Test ``vector.represent_as(PolarVector)``.""" + polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) + + assert isinstance(polar, PolarVector) + assert polar.r == Quantity([1, 2, 3, 4], u.kpc) + assert polar.phi == Quantity([0, 1, 2, 3], u.rad) + + # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + # def test_spherical_to_lnpolar(self, vector): + # """Test ``vector.represent_as(LnPolarVector)``.""" + # assert False + + # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + # def test_spherical_to_log10polar(self, vector): + # """Test ``vector.represent_as(Log10PolarVector)``.""" + # assert False + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_spherical_to_cartesian3d(self, vector): + """Test ``vector.represent_as(Cartesian3DVector)``.""" + cart3d = vector.represent_as( + Cartesian3DVector, z=Quantity([9, 10, 11, 12], u.m) + ) + + assert isinstance(cart3d, Cartesian3DVector) + assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart3d.y == Quantity([5, 6, 7, 8], u.km) + assert cart3d.z == Quantity([9, 10, 11, 12], u.m) + + def test_spherical_to_spherical(self, vector): + """Test ``vector.represent_as(SphericalVector)``.""" + newvec = vector.represent_as(SphericalVector) + assert newvec is vector + + def test_spherical_to_cylindrical(self, vector): + """Test ``vector.represent_as(CylindricalVector)``.""" + cylindrical = vector.represent_as( + CylindricalVector, z=Quantity([9, 10, 11, 12], u.m) + ) + + assert isinstance(cylindrical, CylindricalVector) + assert cylindrical.rho == Quantity([1, 2, 3, 4], u.kpc) + assert cylindrical.phi == Quantity([0, 1, 2, 3], u.rad) + assert cylindrical.z == Quantity([9, 10, 11, 12], u.m) + + +class TestCylindricalVector: + """Test :class:`vector.CylindricalVector`.""" + + @pytest.fixture(scope="class") + def vector(self) -> AbstractVector: + """Return a vector.""" + from vector import CylindricalVector + + return CylindricalVector( + rho=Quantity([1, 2, 3, 4], u.kpc), + phi=Quantity([0, 1, 2, 3], u.rad), + z=Quantity([9, 10, 11, 12], u.m), + ) + + # ========================================================================== + # represent_as + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cylindrical_to_cartesian1d(self, vector): + """Test ``vector.represent_as(Cartesian1DVector)``.""" + cart1d = vector.represent_as(Cartesian1DVector) + + assert isinstance(cart1d, Cartesian1DVector) + assert cart1d.x == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cylindrical_to_radial(self, vector): + """Test ``vector.represent_as(RadialVector)``.""" + radial = vector.represent_as(RadialVector) + + assert isinstance(radial, RadialVector) + assert radial.r == Quantity([1, 2, 3, 4], u.kpc) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cylindrical_to_cartesian2d(self, vector): + """Test ``vector.represent_as(Cartesian2DVector)``.""" + cart2d = vector.represent_as(Cartesian2DVector, y=Quantity([5, 6, 7, 8], u.km)) + + assert isinstance(cart2d, Cartesian2DVector) + assert cart2d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart2d.y == Quantity([5, 6, 7, 8], u.km) + + @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + def test_cylindrical_to_polar(self, vector): + """Test ``vector.represent_as(PolarVector)``.""" + polar = vector.represent_as(PolarVector, phi=Quantity([0, 1, 2, 3], u.rad)) + + assert isinstance(polar, PolarVector) + assert polar.r == Quantity([1, 2, 3, 4], u.kpc) + assert polar.phi == Quantity([0, 1, 2, 3], u.rad) + + # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + # def test_cylindrical_to_lnpolar(self, vector): + # """Test ``vector.represent_as(LnPolarVector)``.""" + # assert False + + # @pytest.mark.filterwarnings("ignore:Irreversible dimension change") + # def test_cylindrical_to_log10polar(self, vector): + # """Test ``vector.represent_as(Log10PolarVector)``.""" + # assert False + + def test_cylindrical_to_cartesian3d(self, vector): + """Test ``vector.represent_as(Cartesian3DVector)``.""" + cart3d = vector.represent_as(Cartesian3DVector, y=Quantity([5, 6, 7, 8], u.km)) + + assert isinstance(cart3d, Cartesian3DVector) + assert cart3d.x == Quantity([1, 2, 3, 4], u.kpc) + assert cart3d.y == Quantity([5, 6, 7, 8], u.km) + assert cart3d.z == Quantity([9, 10, 11, 12], u.m) + + def test_cylindrical_to_spherical(self, vector): + """Test ``vector.represent_as(SphericalVector)``.""" + spherical = vector.represent_as( + SphericalVector, theta=Quantity([4, 5, 6, 7], u.rad) + ) + + assert isinstance(spherical, SphericalVector) + assert spherical.r == Quantity([1, 2, 3, 4], u.kpc) + assert spherical.phi == Quantity([0, 1, 2, 3], u.rad) + assert spherical.theta == Quantity([4, 5, 6, 7], u.rad) + + def test_cylindrical_to_cylindrical(self, vector): + """Test ``vector.represent_as(CylindricalVector)``.""" + newvec = vector.represent_as(CylindricalVector) + assert newvec is vector