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

Commit 3fff19a

Browse files
authored
Validators for the number of responses in multiselect (#362)
* ✨ validators for the number of responses in multiselect * documentation for MaxItems and MinItems validators
1 parent 3ec04a9 commit 3fff19a

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ validators include:
347347
| Required | any | Rejects zero values of the response type | Boolean values pass straight through since the zero value (false) is a valid response |
348348
| MinLength(n) | string | Enforces that a response is at least the given length | |
349349
| MaxLength(n) | string | Enforces that a response is no longer than the given length | |
350+
| MaxItems(n) | []OptionAnswer | Enforces that a response has no more selections of the indicated | |
351+
| MinItems(n) | []OptionAnswer | Enforces that a response has no less selections of the indicated | |
350352

351353
## Help Text
352354

validate.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"errors"
55
"fmt"
66
"reflect"
7+
8+
"github.com/AlecAivazis/survey/v2/core"
79
)
810

911
// Required does not allow an empty value
@@ -58,6 +60,44 @@ func MinLength(length int) Validator {
5860
}
5961
}
6062

63+
// MaxItems requires that the list is no longer than the specified value
64+
func MaxItems(numberItems int) Validator {
65+
// return a validator that checks the length of the list
66+
return func(val interface{}) error {
67+
if list, ok := val.([]core.OptionAnswer); ok {
68+
// if the list is longer than the given value
69+
if len(list) > numberItems {
70+
// yell loudly
71+
return fmt.Errorf("value is too long. Max items is %v", numberItems)
72+
}
73+
} else {
74+
// otherwise we cannot convert the value into a list of answer and cannot enforce length
75+
return fmt.Errorf("cannot impose the length on something other than a list of answers")
76+
}
77+
// the input is fine
78+
return nil
79+
}
80+
}
81+
82+
// MinItems requires that the list is longer or equal in length to the specified value
83+
func MinItems(numberItems int) Validator {
84+
// return a validator that checks the length of the list
85+
return func(val interface{}) error {
86+
if list, ok := val.([]core.OptionAnswer); ok {
87+
// if the list is shorter than the given value
88+
if len(list) < numberItems {
89+
// yell loudly
90+
return fmt.Errorf("value is too long. Min items is %v", numberItems)
91+
}
92+
} else {
93+
// otherwise we cannot convert the value into a list of answer and cannot enforce length
94+
return fmt.Errorf("cannot impose the length on something other than a list of answers")
95+
}
96+
// the input is fine
97+
return nil
98+
}
99+
}
100+
61101
// ComposeValidators is a variadic function used to create one validator from many.
62102
func ComposeValidators(validators ...Validator) Validator {
63103
// return a validator that calls each one sequentially

validate_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package survey
33
import (
44
"math/rand"
55
"testing"
6+
7+
"github.com/AlecAivazis/survey/v2/core"
68
)
79

810
func TestRequired_canSucceedOnPrimitiveTypes(t *testing.T) {
@@ -86,6 +88,40 @@ func randString(n int) string {
8688
return string(b)
8789
}
8890

91+
func TestMaxItems(t *testing.T) {
92+
// the list to test
93+
testList := []core.OptionAnswer{
94+
core.OptionAnswer{Value: "a", Index: 0},
95+
core.OptionAnswer{Value: "b", Index: 1},
96+
core.OptionAnswer{Value: "c", Index: 2},
97+
core.OptionAnswer{Value: "d", Index: 3},
98+
core.OptionAnswer{Value: "e", Index: 4},
99+
core.OptionAnswer{Value: "f", Index: 5},
100+
}
101+
102+
// validate the list
103+
if err := MaxItems(4)(testList); err == nil {
104+
t.Error("No error returned with input greater than 6 items.")
105+
}
106+
}
107+
108+
func TestMinItems(t *testing.T) {
109+
// the list to test
110+
testList := []core.OptionAnswer{
111+
core.OptionAnswer{Value: "a", Index: 0},
112+
core.OptionAnswer{Value: "b", Index: 1},
113+
core.OptionAnswer{Value: "c", Index: 2},
114+
core.OptionAnswer{Value: "d", Index: 3},
115+
core.OptionAnswer{Value: "e", Index: 4},
116+
core.OptionAnswer{Value: "f", Index: 5},
117+
}
118+
119+
// validate the list
120+
if err := MinItems(10)(testList); err == nil {
121+
t.Error("No error returned with input less than 10 items.")
122+
}
123+
}
124+
89125
func TestMaxLength(t *testing.T) {
90126
// the string to test
91127
testStr := randString(150)

0 commit comments

Comments
 (0)