from hypothesis import assume, given, strategies as st
from pytest import raises  # type: ignore

from ppb_vector import Vector
from utils import angle_isclose, isclose, lengths, vectors


@given(v=vectors(), length=st.floats(max_value=0))
def test_scale_negative_length(v: Vector, length: float):
    """Test that Vector.scale_to raises ValueError on negative lengths."""
    assume(length < 0)
    with raises(ValueError):
        v.scale_to(length)


@given(x=vectors(), length=lengths())
def test_scale_to_length(x: Vector, length: float):
    """Test that the length of x.scale_to(length) is length.

    Additionally, scale_to may raise ZeroDivisionError if the vector is null.
    """
    try:
        assert isclose(x.scale_to(length).length, length)
    except ZeroDivisionError:
        assert x == (0, 0)


@given(x=vectors(), length=lengths())
def test_scale_aligned(x: Vector, length: float):
    """Test that x.scale_to(length) is aligned with x."""
    assume(length > 0)
    try:
        assert angle_isclose(x.scale_to(length).angle(x), 0)
    except ZeroDivisionError:
        assert x == (0, 0)

from hypothesis import assume, given

from ppb_vector import Vector
from utils import angle_isclose, floats, isclose, lengths, vectors


@given(x=vectors(), length=floats())
def test_scale_to_length(x: Vector, length: float):
    """Test that the length of x.scale_to(length) is length.

    Additionally, Vector.scale_to may raise:
    - ZeroDivisionError if the vector is null;
    - ValueError if the desired length is negative.

    """
    try:
        assert isclose(x.scale_to(length).length, length)
    except ZeroDivisionError:
        assert x == (0, 0)
    except ValueError:
        assert length < 0


@given(x=vectors(), length=lengths())
def test_scale_aligned(x: Vector, length: float):
    """Test that x.scale_to(length) is aligned with x."""
    assume(length > 0)
    try:
        assert angle_isclose(x.scale_to(length).angle(x), 0)
    except ZeroDivisionError:
        assert x == (0, 0)

--- 
+++ 
@@ -1,24 +1,28 @@
-from hypothesis import assume, given
+from hypothesis import assume, given, strategies as st
+from pytest import raises  # type: ignore
 
 from ppb_vector import Vector
-from utils import angle_isclose, floats, isclose, lengths, vectors
+from utils import angle_isclose, isclose, lengths, vectors
 
 
-@given(x=vectors(), length=floats())
+@given(v=vectors(), length=st.floats(max_value=0))
+def test_scale_negative_length(v: Vector, length: float):
+    """Test that Vector.scale_to raises ValueError on negative lengths."""
+    assume(length < 0)
+    with raises(ValueError):
+        v.scale_to(length)
+
+
+@given(x=vectors(), length=lengths())
 def test_scale_to_length(x: Vector, length: float):
     """Test that the length of x.scale_to(length) is length.
 
-    Additionally, Vector.scale_to may raise:
-    - ZeroDivisionError if the vector is null;
-    - ValueError if the desired length is negative.
-
+    Additionally, scale_to may raise ZeroDivisionError if the vector is null.
     """
     try:
         assert isclose(x.scale_to(length).length, length)
     except ZeroDivisionError:
         assert x == (0, 0)
-    except ValueError:
-        assert length < 0
 
 
 @given(x=vectors(), length=lengths())
tests/scale: Make a separate test for negative lengths

Previously, we didn't check that negative lengths raise a ValueError,
but that *if* a ValueError was raised, then the length was negative.
