From aa2c3d111385f4f246d78c23f970f580af49ac5c Mon Sep 17 00:00:00 2001 From: Flavio Corpa Date: Thu, 18 Jul 2024 11:36:38 +0200 Subject: [PATCH] rough edges --- .github/workflows/ci.yml | 3 ++ LICENSE | 2 +- src/PersonalNumber/Danish.elm | 8 +++- src/PersonalNumber/Finnish.elm | 16 +++++-- src/PersonalNumber/Swedish.elm | 77 ++++++++++++++++------------------ src/Util.elm | 9 +++- tests/DanishTest.elm | 5 +-- tests/FinnishTest.elm | 2 + tests/NorwegianTest.elm | 2 + tests/SwedishTest.elm | 2 + 10 files changed, 72 insertions(+), 54 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ada984..9916b53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,5 +48,8 @@ jobs: - name: run make, format, tests (see package.json) run: npm test + - name: elm-review + run: npx elm-review --template jfmengels/elm-review-unused/example + - name: build run: npm run build diff --git a/LICENSE b/LICENSE index cbeb1c1..fd8d19e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright © 2024 Scrive AB +Copyright © 2024 Scrive AB, 2019 Niklas Holmgren Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/PersonalNumber/Danish.elm b/src/PersonalNumber/Danish.elm index 1436650..b5b529d 100644 --- a/src/PersonalNumber/Danish.elm +++ b/src/PersonalNumber/Danish.elm @@ -33,7 +33,6 @@ where DDMMYY is the day, month and year of birth. import Json.Decode as Decode import Json.Encode as Encode -import Maybe.Extra as Maybe import Parser exposing ((|.), Parser, chompIf, getChompedString) import Util exposing (digit, getSerialPart, stringLength, validateDate, whitespace) @@ -58,9 +57,14 @@ personalNumberParser = |. stringLength 6 |. Parser.oneOf [ chompIf (\c -> c == '-') - -- FIXME: fix only numbers!! + |. digit + |. digit + |. digit |. digit , digit + |. digit + |. digit + |. digit ] ) |> Parser.map PersonalNumber diff --git a/src/PersonalNumber/Finnish.elm b/src/PersonalNumber/Finnish.elm index 7625f4f..89e80e1 100644 --- a/src/PersonalNumber/Finnish.elm +++ b/src/PersonalNumber/Finnish.elm @@ -36,9 +36,8 @@ import Basics.Extra exposing (flip) import Json.Decode as Decode exposing (Decoder) import Json.Encode as Encode import List.Extra as List -import Maybe.Extra as Maybe import Parser exposing ((|.), Parser, chompIf, getChompedString) -import Util exposing (getSerialPart, stringLength, validateDate, whitespace) +import Util exposing (char, digit, getSerialPart, validateDate, whitespace) {-| An opaque type representing a valid personal number. @@ -70,9 +69,18 @@ personalNumberParser = (getChompedString <| Parser.succeed () |. whitespace - |. stringLength 6 + |. digit + |. digit + |. digit + |. digit + |. digit + |. digit |. chompIf (\c -> c == '-' || c == '+' || c == 'A') - |. stringLength 4 + |. digit + |. digit + |. digit + -- checksum + |. char ) |> Parser.map PersonalNumber diff --git a/src/PersonalNumber/Swedish.elm b/src/PersonalNumber/Swedish.elm index 6e735ae..7b25e0e 100644 --- a/src/PersonalNumber/Swedish.elm +++ b/src/PersonalNumber/Swedish.elm @@ -35,7 +35,6 @@ temporary visitors. import Json.Decode import Json.Encode import Parser exposing ((|.), Parser, getChompedString) -import Result.Extra as Result import String import Util exposing (stringLength, whitespace) @@ -91,8 +90,8 @@ personalNumberParser = |> Parser.map PNR -checkFormat : String -> Result ValidationError String -checkFormat str = +validateFormat : String -> Result ValidationError String +validateFormat str = case Parser.run personalNumberParser str of Ok pnr -> Ok (toString pnr) @@ -103,45 +102,39 @@ checkFormat str = verifyChecksum : String -> Result ValidationError String verifyChecksum str = - case Parser.run personalNumberParser str of - Ok pnr -> - let - checksum = - pnr - |> toString - |> String.split "" - |> List.reverse - |> List.take 10 - |> List.reverse - |> List.map String.toInt - |> List.map (Maybe.withDefault -1) - |> List.indexedMap (\a b -> ( a, b )) - |> List.map - (\( i, a ) -> - if modBy 2 i == 0 then - a * 2 - - else - a - ) - |> List.map - (\a -> - if a > 9 then - 1 + (a - 10) - - else - a - ) - |> List.foldl (+) 0 - in - if modBy 10 checksum == 0 then - Ok str - - else - Err InvalidChecksum + let + checksum = + str + |> String.split "" + |> List.reverse + |> List.take 10 + |> List.reverse + |> List.map String.toInt + |> List.map (Maybe.withDefault -1) + |> List.indexedMap (\a b -> ( a, b )) + |> List.map + (\( i, a ) -> + if modBy 2 i == 0 then + a * 2 + + else + a + ) + |> List.map + (\a -> + if a > 9 then + 1 + (a - 10) + + else + a + ) + |> List.foldl (+) 0 + in + if modBy 10 checksum == 0 then + Ok str - Err _ -> - Err InvalidChecksum + else + Err InvalidChecksum numberType : String -> Result ValidationError PersonalNumber @@ -197,7 +190,7 @@ fromString str = digits = String.right 4 pnr in - checkFormat (date ++ digits) + validateFormat (date ++ digits) |> Result.andThen verifyChecksum |> Result.andThen numberType diff --git a/src/Util.elm b/src/Util.elm index 0abb424..5fbb9e2 100644 --- a/src/Util.elm +++ b/src/Util.elm @@ -1,4 +1,4 @@ -module Util exposing (digit, getSerialPart, stringLength, validateDate, whitespace) +module Util exposing (char, digit, getSerialPart, stringLength, validateDate, whitespace) import List.Extra as List import Parser exposing ((|.), Parser, Step(..), chompIf, chompWhile, getChompedString) @@ -11,7 +11,12 @@ whitespace = digit : Parser () digit = - chompWhile Char.isDigit + chompIf Char.isDigit + + +char : Parser () +char = + chompIf Char.isAlphaNum stringLength : Int -> Parser String diff --git a/tests/DanishTest.elm b/tests/DanishTest.elm index 792e35c..2dda9da 100644 --- a/tests/DanishTest.elm +++ b/tests/DanishTest.elm @@ -21,9 +21,8 @@ suite = |> Expect.equal (Ok "160688-4523") , test "should not accept a PNR with less than 10 digits" <| \_ -> Expect.err (PersonalNumber.fromString "160688") - , skip <| - test "should not accept an invalid PNR with other characters than digits" <| - \_ -> Expect.err (PersonalNumber.fromString "160688-45MM") + , test "should not accept an invalid PNR with other characters than digits" <| + \_ -> Expect.err (PersonalNumber.fromString "160688-45MM") , test "should not accept a PNR that is not a valid date" <| \_ -> Expect.err (PersonalNumber.fromString "3206884523") , test "should not accept an empty value" <| diff --git a/tests/FinnishTest.elm b/tests/FinnishTest.elm index 49eea69..d892f5e 100644 --- a/tests/FinnishTest.elm +++ b/tests/FinnishTest.elm @@ -21,6 +21,8 @@ suite = |> Expect.equal (Ok "111111-111C") , test "should not accept a PNR without the last four digits" <| \_ -> Expect.err (PersonalNumber.fromString "200866001386") + , test "should not accept a PNR with alpha characters not in checknum position" <| + \_ -> Expect.err (PersonalNumber.fromString "200A66001386") , test "should not accept an invalid PNR with the correct format" <| \_ -> Expect.err (PersonalNumber.fromString " - - -- ") , test "should not accept a PNR that is not a valid date" <| diff --git a/tests/NorwegianTest.elm b/tests/NorwegianTest.elm index fe47105..c6b7e31 100644 --- a/tests/NorwegianTest.elm +++ b/tests/NorwegianTest.elm @@ -31,6 +31,8 @@ suite = |> Expect.equal (Ok "19118438739") , test "should not accept a PNR without the last four digits" <| \_ -> Expect.err (fromString "200866001386") + , test "should not accept a PNR with alpha characters not in checknum position" <| + \_ -> Expect.err (PersonalNumber.fromString "200A66001386") , test "should not accept an invalid PNR with the correct format" <| \_ -> Expect.err (fromString " - - -- ") , test "should not accept a PNR that is not a valid date" <| diff --git a/tests/SwedishTest.elm b/tests/SwedishTest.elm index d382907..d149864 100644 --- a/tests/SwedishTest.elm +++ b/tests/SwedishTest.elm @@ -39,6 +39,8 @@ suite = \_ -> Expect.err (fromString "19921208") , test "should not accept an invalid PNR with the correct format" <| \_ -> Expect.err (fromString "00000000-0000") + , test "should not accept a PNR with alpha characters not in checknum position" <| + \_ -> Expect.err (PersonalNumber.fromString "1992A208-1286") , test "should not accept a PNR that is not a valid date" <| \_ -> Expect.err (fromString "19921308-1285") , test "should not accept a PNR with an invalid checksum" <|