add Block + Component, add TextComponent with min, max and regex validators and early NumberComponent
This commit is contained in:
21
internal/block/text_component/validators/max_length.go
Normal file
21
internal/block/text_component/validators/max_length.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package text_component_validators
|
||||
|
||||
import (
|
||||
"blocky/internal/block/text_component"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func MaxLength(max int) text_component.TextComponentOption {
|
||||
return func(c *text_component.TextComponentConfig) {
|
||||
c.Validators = append(c.Validators, func(value any) error {
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("provided value bust be a string: %v", value)
|
||||
}
|
||||
if len(s) > max {
|
||||
return fmt.Errorf("must be at most %d characters", max)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
36
internal/block/text_component/validators/max_length_test.go
Normal file
36
internal/block/text_component/validators/max_length_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package text_component_validators
|
||||
|
||||
import (
|
||||
"blocky/internal/block/text_component"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMaxLength(t *testing.T) {
|
||||
cfg := &text_component.TextComponentConfig{}
|
||||
MaxLength(10)(cfg)
|
||||
|
||||
if len(cfg.Validators) != 1 {
|
||||
t.Fatalf("expect 1 validator, got %d", len(cfg.Validators))
|
||||
}
|
||||
|
||||
validate := cfg.Validators[0]
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
value string
|
||||
wantErr bool
|
||||
}{
|
||||
{"below value", "01234", false},
|
||||
{"equal to value", "0123456789", false},
|
||||
{"above value", "abcdefghjilkmnopqrstuvwxyz", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := validate(tt.value)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("validate(%v) error = %v, wantErr %v", tt.value, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
21
internal/block/text_component/validators/min_length.go
Normal file
21
internal/block/text_component/validators/min_length.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package text_component_validators
|
||||
|
||||
import (
|
||||
"blocky/internal/block/text_component"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func MinLength(min int) text_component.TextComponentOption {
|
||||
return func(c *text_component.TextComponentConfig) {
|
||||
c.Validators = append(c.Validators, func(value any) error {
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("provided value bust be a string: %v", value)
|
||||
}
|
||||
if len(s) < min {
|
||||
return fmt.Errorf("must be at least %d characters", min)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
36
internal/block/text_component/validators/min_length_test.go
Normal file
36
internal/block/text_component/validators/min_length_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package text_component_validators
|
||||
|
||||
import (
|
||||
"blocky/internal/block/text_component"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMinLength(t *testing.T) {
|
||||
cfg := &text_component.TextComponentConfig{}
|
||||
MinLength(10)(cfg)
|
||||
|
||||
if len(cfg.Validators) != 1 {
|
||||
t.Fatalf("expect 1 validator, got %d", len(cfg.Validators))
|
||||
}
|
||||
|
||||
validate := cfg.Validators[0]
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
value string
|
||||
wantErr bool
|
||||
}{
|
||||
{"below value", "01234", true},
|
||||
{"equal to value", "0123456789", false},
|
||||
{"above value", "abcdefghjilkmnopqrstuvwxyz", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := validate(tt.value)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("validate(%v) error = %v, wantErr %v", tt.value, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
24
internal/block/text_component/validators/regex.go
Normal file
24
internal/block/text_component/validators/regex.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package text_component_validators
|
||||
|
||||
import (
|
||||
"blocky/internal/block/text_component"
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func Regex(pattern string) text_component.TextComponentOption {
|
||||
re := regexp.MustCompile(pattern)
|
||||
|
||||
return func(c *text_component.TextComponentConfig) {
|
||||
c.Validators = append(c.Validators, func(value any) error {
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("provided value bust be a string: %v", value)
|
||||
}
|
||||
if !re.MatchString(s) {
|
||||
return fmt.Errorf("must match pattern %s", pattern)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
33
internal/block/text_component/validators/regex_test.go
Normal file
33
internal/block/text_component/validators/regex_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package text_component_validators
|
||||
|
||||
import (
|
||||
"blocky/internal/block/text_component"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegex(t *testing.T) {
|
||||
cfg := &text_component.TextComponentConfig{}
|
||||
Regex("^\\d+$")(cfg)
|
||||
|
||||
validate := cfg.Validators[0]
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
value string
|
||||
wantErr bool
|
||||
}{
|
||||
{"just numbers", "123", false},
|
||||
{"just letters", "abc", true},
|
||||
{"numbers and letters", "abc", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := validate(tt.value)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("validate(%v) error = %v, wantErr %v", tt.value, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user