Play

Check-in [635fab0eeb]
Login
Overview
Comment:SemanticVersion now returns descriptive error messages.
Timelines: family | ancestors | descendants | both | modules
Files: files | file ages | folders
SHA3-256: 635fab0eeb541129ba3a153cfed2ca30c7328083ddff8f43772899070f277b44
User & Date: robin.hansen on 2021-02-14 10:59:51
Other Links: branch diff | manifest | tags
Context
2021-02-14
11:47
Add json decoder for PackageMetadata. Missing validation of key values in dependencies field, and sh... check-in: 38d406f888 user: robin.hansen tags: modules
10:59
SemanticVersion now returns descriptive error messages. check-in: 635fab0eeb user: robin.hansen tags: modules
10:43
On second thought, better be strict with semantic versioning. check-in: 28d1fb8fd8 user: robin.hansen tags: modules
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Play/Data/SemanticVersion.elm from [92b365e1e7] to [a5448c2ad1].

1

2
3
4
5
6
7
8
9
10







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
module Play.Data.SemanticVersion exposing

    ( SemanticVersion
    , fromString
    )


type SemanticVersion
    = SemanticVersion Int Int Int









fromString : String -> Result () SemanticVersion
fromString str =
    case String.split "." str of
        [ major, minor, patch ] ->
            toInt major minor patch

        _ ->
            Err ()


toInt : String -> String -> String -> Result () SemanticVersion
toInt majorStr minorStr patchStr =
    let
        intVersions =
            [ majorStr, minorStr, patchStr ]
                |> List.filterMap String.toInt
    in
    case intVersions of
        [ major, minor, patch ] ->
            if major < 0 || minor < 0 || patch < 0 then
                Err ()

            else if major == 0 && minor == 0 && patch < 1 then
                Err ()

            else
                Ok <| SemanticVersion major minor patch

        _ ->
            Err ()

>
|








>
>
>
>
>
>
>
|



|


|


|
|








|


|





|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
module Play.Data.SemanticVersion exposing
    ( ParseError(..)
    , SemanticVersion
    , fromString
    )


type SemanticVersion
    = SemanticVersion Int Int Int


type ParseError
    = InvalidFormat String
    | ExpectedInteger String
    | NegativeVersions String
    | LessThanMinimumVersion String


fromString : String -> Result ParseError SemanticVersion
fromString str =
    case String.split "." str of
        [ major, minor, patch ] ->
            toInt str major minor patch

        _ ->
            Err <| InvalidFormat str


toInt : String -> String -> String -> String -> Result ParseError SemanticVersion
toInt originalStr majorStr minorStr patchStr =
    let
        intVersions =
            [ majorStr, minorStr, patchStr ]
                |> List.filterMap String.toInt
    in
    case intVersions of
        [ major, minor, patch ] ->
            if major < 0 || minor < 0 || patch < 0 then
                Err <| NegativeVersions originalStr

            else if major == 0 && minor == 0 && patch < 1 then
                Err <| LessThanMinimumVersion originalStr

            else
                Ok <| SemanticVersion major minor patch

        _ ->
            Err <| ExpectedInteger originalStr

Modified tests/Test/Data/SemanticVersion.elm from [7aa88bfaa0] to [1c381630ef].

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
                    , "10.100.1000"
                    , "0.0.1"
                    , "0.1.0"
                    ]
        , test "Cannot contain more than three parts" <|
            \_ ->
                SemanticVersion.fromString "1.2.3.4"
                    |> Expect.err
        , test "Cannot contain less than three parts" <|
            \_ ->
                PlayExpect.allErr SemanticVersion.fromString
                    [ "1"
                    , "1.2"
                    ]
        , test "Cannot be empty string" <|
            \_ ->
                SemanticVersion.fromString ""
                    |> Expect.err
        , test "Must be numbers" <|
            \_ ->
                PlayExpect.allErr SemanticVersion.fromString
                    [ "A"
                    , "*"
                    , "~"
                    , "1.0.x"
                    , "1.0.~"
                    , "~1.0.0"
                    , "1.0.0-alpha1"
                    , "alpha.1"
                    ]
        , test "Minimum version is 0.0.1" <|
            \_ ->
                SemanticVersion.fromString "0.0.0"
                    |> Expect.err
        , test "Cannot contain negative versions" <|
            \_ ->
                PlayExpect.allErr SemanticVersion.fromString
                    [ "-1.0.0"
                    , "1.-2.0"
                    , "1.2.-1"
                    ]
        ]







|


|
|
|




|


|
|
|
|
|
|
|
|
|




|


|
|
|
|


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
                    , "10.100.1000"
                    , "0.0.1"
                    , "0.1.0"
                    ]
        , test "Cannot contain more than three parts" <|
            \_ ->
                SemanticVersion.fromString "1.2.3.4"
                    |> Expect.equal (Err <| SemanticVersion.InvalidFormat "1.2.3.4")
        , test "Cannot contain less than three parts" <|
            \_ ->
                PlayExpect.allEqual SemanticVersion.fromString
                    [ ( "1", Err <| SemanticVersion.InvalidFormat "1" )
                    , ( "1.2", Err <| SemanticVersion.InvalidFormat "1.2" )
                    ]
        , test "Cannot be empty string" <|
            \_ ->
                SemanticVersion.fromString ""
                    |> Expect.equal (Err <| SemanticVersion.InvalidFormat "")
        , test "Must be numbers" <|
            \_ ->
                PlayExpect.allEqual SemanticVersion.fromString
                    [ ( "A", Err <| SemanticVersion.InvalidFormat "A" )
                    , ( "*", Err <| SemanticVersion.InvalidFormat "*" )
                    , ( "~", Err <| SemanticVersion.InvalidFormat "~" )
                    , ( "1.0.x", Err <| SemanticVersion.ExpectedInteger "1.0.x" )
                    , ( "1.0.~", Err <| SemanticVersion.ExpectedInteger "1.0.~" )
                    , ( "~1.0.0", Err <| SemanticVersion.ExpectedInteger "~1.0.0" )
                    , ( "1.0.0-alpha1", Err <| SemanticVersion.ExpectedInteger "1.0.0-alpha1" )
                    , ( "alpha.1", Err <| SemanticVersion.InvalidFormat "alpha.1" )
                    ]
        , test "Minimum version is 0.0.1" <|
            \_ ->
                SemanticVersion.fromString "0.0.0"
                    |> Expect.equal (Err <| SemanticVersion.LessThanMinimumVersion "0.0.0")
        , test "Cannot contain negative versions" <|
            \_ ->
                PlayExpect.allEqual SemanticVersion.fromString
                    [ ( "-1.0.0", Err <| SemanticVersion.NegativeVersions "-1.0.0" )
                    , ( "1.-2.0", Err <| SemanticVersion.NegativeVersions "1.-2.0" )
                    , ( "1.2.-3", Err <| SemanticVersion.NegativeVersions "1.2.-3" )
                    ]
        ]

Modified tests/Test/PlayExpect.elm from [d38c5f4a89] to [1b415049a2].

1

2
3
4
5
6
7
8
9
..
34
35
36
37
38
39
40









module Test.PlayExpect exposing

    ( allErr
    , allOk
    )

import Expect


allOk : (a -> Result err ok) -> List a -> Expect.Expectation
................................................................................
                Ok _ ->
                    Expect.fail <| "Expected Err for input " ++ Debug.toString original ++ ", was: " ++ Debug.toString result

                Err _ ->
                    Expect.pass
    in
    Expect.all expectationList fn










>
|







 







>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
..
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
module Test.PlayExpect exposing
    ( allEqual
    , allErr
    , allOk
    )

import Expect


allOk : (a -> Result err ok) -> List a -> Expect.Expectation
................................................................................
                Ok _ ->
                    Expect.fail <| "Expected Err for input " ++ Debug.toString original ++ ", was: " ++ Debug.toString result

                Err _ ->
                    Expect.pass
    in
    Expect.all expectationList fn


allEqual : (a -> b) -> List ( a, b ) -> Expect.Expectation
allEqual fn values =
    let
        expectationList =
            List.map (\( input, expected ) -> \f -> Expect.equal expected (f input)) values
    in
    Expect.all expectationList fn