<commit_before>module Generic.Curve2d
    exposing
        ( rotation
        , scaling
        , translation
        )

import Fuzz exposing (Fuzzer)
import OpenSolid.Geometry.Expect as Expect
import OpenSolid.Geometry.Fuzz as Fuzz
import OpenSolid.Point2d as Point2d exposing (Point2d)
import OpenSolid.Vector2d as Vector2d exposing (Vector2d)
import Test exposing (Test)


parameterValue : Fuzzer Float
parameterValue =
    Fuzz.floatRange 0 1


scaling : Fuzzer a -> (Point2d -> Float -> a -> a) -> (a -> Float -> Point2d) -> Test
scaling curveFuzzer scaleAbout pointOn =
    Test.fuzz4
        curveFuzzer
        Fuzz.point2d
        Fuzz.scalar
        parameterValue
        "scaleAbout"
        (\curve basePoint scale t ->
            let
                scaledCurve =
                    scaleAbout basePoint scale curve

                originalPoint =
                    pointOn curve t

                pointOnScaledCurve =
                    pointOn scaledCurve t

                scaledPoint =
                    Point2d.scaleAbout basePoint scale originalPoint
            in
            pointOnScaledCurve |> Expect.point2d scaledPoint
        )


translation : Fuzzer a -> (Vector2d -> a -> a) -> (a -> Float -> Point2d) -> Test
translation curveFuzzer translateBy pointOn =
    Test.fuzz3
        curveFuzzer
        Fuzz.vector2d
        parameterValue
        "translateBy"
        (\curve displacement t ->
            let
                translatedCurve =
                    translateBy displacement curve

                originalPoint =
                    pointOn curve t

                pointOnTranslatedCurve =
                    pointOn translatedCurve t

                translatedPoint =
                    Point2d.translateBy displacement originalPoint
            in
            pointOnTranslatedCurve |> Expect.point2d translatedPoint
        )


rotation : Fuzzer a -> (Point2d -> Float -> a -> a) -> (a -> Float -> Point2d) -> Test
rotation curveFuzzer rotateAround pointOn =
    Test.fuzz4
        curveFuzzer
        Fuzz.point2d
        (Fuzz.floatRange (-2 * pi) (2 * pi))
        parameterValue
        "rotateAround"
        (\curve centerPoint angle t ->
            let
                rotatedCurve =
                    rotateAround centerPoint angle curve

                originalPoint =
                    pointOn curve t

                pointOnRotatedCurve =
                    pointOn rotatedCurve t

                rotatedPoint =
                    Point2d.rotateAround centerPoint angle originalPoint
            in
            pointOnRotatedCurve |> Expect.point2d rotatedPoint
        )<commit_msg>Refactor generic curve tests<commit_after>module Generic.Curve2d
    exposing
        ( Config
        , rotation
        , scaling
        , translation
        )

import Fuzz exposing (Fuzzer)
import OpenSolid.Geometry.Expect as Expect
import OpenSolid.Geometry.Fuzz as Fuzz
import OpenSolid.Point2d as Point2d exposing (Point2d)
import OpenSolid.Vector2d as Vector2d exposing (Vector2d)
import Test exposing (Test)


type alias Config curve =
    { fuzzer : Fuzzer curve
    , pointOn : curve -> Float -> Point2d
    , derivative : curve -> Float -> Vector2d
    }


parameterValue : Fuzzer Float
parameterValue =
    Fuzz.floatRange 0 1


scaling : Config curve -> (Point2d -> Float -> curve -> curve) -> Test
scaling config scaleAbout =
    Test.fuzz4
        config.fuzzer
        Fuzz.point2d
        Fuzz.scalar
        parameterValue
        "scaleAbout"
        (\curve basePoint scale t ->
            let
                scaledCurve =
                    scaleAbout basePoint scale curve

                originalPoint =
                    config.pointOn curve t

                pointOnScaledCurve =
                    config.pointOn scaledCurve t

                scaledPoint =
                    Point2d.scaleAbout basePoint scale originalPoint
            in
            pointOnScaledCurve |> Expect.point2d scaledPoint
        )


translation : Config curve -> (Vector2d -> curve -> curve) -> Test
translation config translateBy =
    Test.fuzz3
        config.fuzzer
        Fuzz.vector2d
        parameterValue
        "translateBy"
        (\curve displacement t ->
            let
                translatedCurve =
                    translateBy displacement curve

                originalPoint =
                    config.pointOn curve t

                pointOnTranslatedCurve =
                    config.pointOn translatedCurve t

                translatedPoint =
                    Point2d.translateBy displacement originalPoint
            in
            pointOnTranslatedCurve |> Expect.point2d translatedPoint
        )


rotation : Config curve -> (Point2d -> Float -> curve -> curve) -> Test
rotation config rotateAround =
    Test.fuzz4
        config.fuzzer
        Fuzz.point2d
        (Fuzz.floatRange (-2 * pi) (2 * pi))
        parameterValue
        "rotateAround"
        (\curve centerPoint angle t ->
            let
                rotatedCurve =
                    rotateAround centerPoint angle curve

                originalPoint =
                    config.pointOn curve t

                pointOnRotatedCurve =
                    config.pointOn rotatedCurve t

                rotatedPoint =
                    Point2d.rotateAround centerPoint angle originalPoint
            in
            pointOnRotatedCurve |> Expect.point2d rotatedPoint
        )
{'fraction_non_alphanumeric': 0.05551497443389335, 'fraction_numerical': 0.010409057706355003, 'mean_word_length': 1.526291512915129, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '741934', 'n_tokens_mistral': 1446, 'n_tokens_neox': 1335, 'n_words': 375}