Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

Validators for the number of responses in multiselect #362

Merged
merged 2 commits into from Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -347,6 +347,8 @@ validators include:
| Required | any | Rejects zero values of the response type | Boolean values pass straight through since the zero value (false) is a valid response |
| MinLength(n) | string | Enforces that a response is at least the given length | |
| MaxLength(n) | string | Enforces that a response is no longer than the given length | |
| MaxItems(n) | []OptionAnswer | Enforces that a response has no more selections of the indicated | |
| MinItems(n) | []OptionAnswer | Enforces that a response has no less selections of the indicated | |

## Help Text

Expand Down
40 changes: 40 additions & 0 deletions validate.go
Expand Up @@ -4,6 +4,8 @@ import (
"errors"
"fmt"
"reflect"

"github.com/AlecAivazis/survey/v2/core"
)

// Required does not allow an empty value
Expand Down Expand Up @@ -58,6 +60,44 @@ func MinLength(length int) Validator {
}
}

// MaxItems requires that the list is no longer than the specified value
func MaxItems(numberItems int) Validator {
// return a validator that checks the length of the list
return func(val interface{}) error {
if list, ok := val.([]core.OptionAnswer); ok {
// if the list is longer than the given value
if len(list) > numberItems {
// yell loudly
return fmt.Errorf("value is too long. Max items is %v", numberItems)
}
} else {
// otherwise we cannot convert the value into a list of answer and cannot enforce length
return fmt.Errorf("cannot impose the length on something other than a list of answers")
}
// the input is fine
return nil
}
}

// MinItems requires that the list is longer or equal in length to the specified value
func MinItems(numberItems int) Validator {
// return a validator that checks the length of the list
return func(val interface{}) error {
if list, ok := val.([]core.OptionAnswer); ok {
// if the list is shorter than the given value
if len(list) < numberItems {
// yell loudly
return fmt.Errorf("value is too long. Min items is %v", numberItems)
}
} else {
// otherwise we cannot convert the value into a list of answer and cannot enforce length
return fmt.Errorf("cannot impose the length on something other than a list of answers")
}
// the input is fine
return nil
}
}

// ComposeValidators is a variadic function used to create one validator from many.
func ComposeValidators(validators ...Validator) Validator {
// return a validator that calls each one sequentially
Expand Down
36 changes: 36 additions & 0 deletions validate_test.go
Expand Up @@ -3,6 +3,8 @@ package survey
import (
"math/rand"
"testing"

"github.com/AlecAivazis/survey/v2/core"
)

func TestRequired_canSucceedOnPrimitiveTypes(t *testing.T) {
Expand Down Expand Up @@ -86,6 +88,40 @@ func randString(n int) string {
return string(b)
}

func TestMaxItems(t *testing.T) {
// the list to test
testList := []core.OptionAnswer{
core.OptionAnswer{Value: "a", Index: 0},
core.OptionAnswer{Value: "b", Index: 1},
core.OptionAnswer{Value: "c", Index: 2},
core.OptionAnswer{Value: "d", Index: 3},
core.OptionAnswer{Value: "e", Index: 4},
core.OptionAnswer{Value: "f", Index: 5},
}

// validate the list
if err := MaxItems(4)(testList); err == nil {
t.Error("No error returned with input greater than 6 items.")
}
}

func TestMinItems(t *testing.T) {
// the list to test
testList := []core.OptionAnswer{
core.OptionAnswer{Value: "a", Index: 0},
core.OptionAnswer{Value: "b", Index: 1},
core.OptionAnswer{Value: "c", Index: 2},
core.OptionAnswer{Value: "d", Index: 3},
core.OptionAnswer{Value: "e", Index: 4},
core.OptionAnswer{Value: "f", Index: 5},
}

// validate the list
if err := MinItems(10)(testList); err == nil {
t.Error("No error returned with input less than 10 items.")
}
}

func TestMaxLength(t *testing.T) {
// the string to test
testStr := randString(150)
Expand Down