Skip to content

Commit

Permalink
Add expectation to regex validation (dillonkearns#11)
Browse files Browse the repository at this point in the history
* Added expectation parameter to pass in expected outcome if regex validation fails
  • Loading branch information
ZeldaIV committed Dec 4, 2021
1 parent 1da09de commit d66a0e8
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
6 changes: 4 additions & 2 deletions src/Cli/Program.elm
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,11 @@ run (Config { optionsParsers }) argv versionMessage =
++ (validationErrors
|> List.map
(\{ name, invalidReason } ->
"`"
"Invalid "
++ "`--"
++ name
++ "` failed a validation. "
++ "` option."
++ "\n"
++ invalidReason
)
|> String.join "\n"
Expand Down
39 changes: 38 additions & 1 deletion src/Cli/Validate.elm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Cli.Validate exposing (predicate, ValidationResult(..), regex)
module Cli.Validate exposing (predicate, ValidationResult(..), regex, regexWithExpectation)

{-| This module contains helper functions for performing validations (see the
"validate..." functions in `Cli.Option`).
Expand Down Expand Up @@ -83,3 +83,40 @@ regex regexPattern checkString =

else
Invalid ("Must be of form /" ++ regexPattern ++ "/")

{-| A helper for regex validations with an additional expectation message.
programConfig : Program.Config String
programConfig =
Program.config
|> Program.add
(OptionsParser.build identity
|> OptionsParser.with
(Option.requiredKeywordArg "name"
|> Option.validate
(Cli.Validate.regexWithExpectation "I expected this to be" "^[A-Z][A-Za-z_]*")
)
)
If the validation fails, the user gets output like this:
```shell
$ ./greet --name john
Validation errors:
`name` failed a validation. I expected this to be matching "^[A-Z][A-Za-z_]*" but got 'john'
Value was:
"john"
```
-}
regexWithExpectation : String -> String -> String -> ValidationResult
regexWithExpectation expectation regexPattern checkString =
case regex regexPattern checkString of
Valid ->
Valid

Invalid _ ->
Invalid (expectation ++ " matching \"" ++ regexPattern ++ "\", but got '" ++ checkString ++ "'")


26 changes: 26 additions & 0 deletions tests/OptionsParserTests.elm
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,32 @@ all =
|> OptionsParser.end
)
[ { name = "name", invalidReason = "Must be 3 characters long" } ]
, test "fails with expectation when regexWithExpectation validation function fails" <|
\() ->
expectValidationErrors [ "--scalar-codecs", "src/ModuleName" ]
(OptionsParser.build identity
|> OptionsParser.with
(Option.optionalKeywordArg "scalar-codecs"
|> Option.validateIfPresent
(\moduleName ->
Validate.regexWithExpectation "I expected an Elm module name" "^[A-Z][A-Za-z_]*(\\.[A-Z][A-Za-z_]*)*$" moduleName)
)
|> OptionsParser.end
)
[ { name = "scalar-codecs", invalidReason = "I expected an Elm module name matching \"^[A-Z][A-Za-z_]*(\\.[A-Z][A-Za-z_]*)*$\", but got 'src/ModuleName'" } ]
, test "succeeds when regexWithExpectation validation function passes" <|
\() ->
expectMatch [ "--scalar-codecs", "ModuleName" ]
(OptionsParser.build identity
|> OptionsParser.with
(Option.optionalKeywordArg "scalar-codecs"
|> Option.validateIfPresent
(\moduleName ->
Validate.regexWithExpectation "I expected an Elm module name" "^[A-Z][A-Za-z_]*(\\.[A-Z][A-Za-z_]*)*$" moduleName)
)
|> OptionsParser.end
)
(Just "ModuleName")
, test "succeeds when validation function passes" <|
\() ->
expectMatch [ "--name", "Bob" ]
Expand Down

0 comments on commit d66a0e8

Please sign in to comment.