Skip to content

Commit

Permalink
Fix length validations to count the length of the string using by utf…
Browse files Browse the repository at this point in the history
…8.RuneCountInString(). (goadesign#740)

* Fix length validations to count the length of the string using by utf8.RuneCountInString().

* Add SimpleImport to MediaType and UserMediaType.

* Fix generation codes of InvalidLengthError

* Add a length validation test for string type
  • Loading branch information
ikawaha committed Dec 13, 2016
1 parent 7fc6b55 commit 7b80871
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 10 deletions.
15 changes: 8 additions & 7 deletions goagen/codegen/validation.go
Expand Up @@ -260,6 +260,7 @@ func ValidationChecker(att *design.AttributeDefinition, nonzero, required, hasDe
"context": context,
"target": target,
"targetVal": t,
"string": att.Type.Name() == "string",
"array": att.Type.IsArray(),
"hash": att.Type.IsHash(),
"depth": depth,
Expand Down Expand Up @@ -411,13 +412,13 @@ const (
{{ if .isPointer }}{{ tabs $depth }}}
{{ end }}{{ tabs .depth }}}`

lengthValTmpl = `{{ $depth := or (and .isPointer (add .depth 1)) .depth }}{{/*
*/}}{{ $target := or (and (or (or .array .hash) .nonzero) .target) .targetVal }}{{/*
*/}}{{ if .isPointer }}{{ tabs .depth }}if {{ .target }} != nil {
{{ end }}{{ tabs .depth }} if len({{ $target }}) {{ if .isMinLength }}<{{ else }}>{{ end }} {{ if .isMinLength }}{{ .minLength }}{{ else }}{{ .maxLength }}{{ end }} {
{{ tabs $depth }} err = goa.MergeErrors(err, goa.InvalidLengthError(` + "`" + `{{ .context }}` + "`" + `, {{ $target }}, len({{ $target }}), {{ if .isMinLength }}{{ .minLength }}, true{{ else }}{{ .maxLength }}, false{{ end }}))
{{ if .isPointer }}{{ tabs $depth }}}
{{ end }}{{ tabs .depth }}}`
lengthValTmpl = `{{$depth := or (and .isPointer (add .depth 1)) .depth}}{{/*
*/}}{{$target := or (and (or (or .array .hash) .nonzero) .target) .targetVal}}{{/*
*/}}{{if .isPointer}}{{tabs .depth}}if {{.target}} != nil {
{{end}}{{tabs .depth}} if {{if .string}}utf8.RuneCountInString({{$target}}){{else}}len({{$target}}){{end}} {{if .isMinLength}}<{{else}}>{{end}} {{if .isMinLength}}{{.minLength}}{{else}}{{.maxLength}}{{end}} {
{{tabs $depth}} err = goa.MergeErrors(err, goa.InvalidLengthError(` + "`" + `{{.context}}` + "`" + `, {{$target}}, {{if .string}}utf8.RuneCountInString({{$target}}){{else}}len({{$target}}){{end}}, {{if .isMinLength}}{{.minLength}}, true{{else}}{{.maxLength}}, false{{end}}))
{{if .isPointer}}{{tabs $depth}}}
{{end}}{{tabs .depth}}}`

requiredValTmpl = `{{ $att := index $.attribute.Type.ToObject .required }}{{/*
*/}}{{ if and (not $.private) (eq $att.Type.Kind 4) }}{{ tabs $.depth }}if {{ $.target }}.{{ goifyAtt $att .required true }} == "" {
Expand Down
26 changes: 23 additions & 3 deletions goagen/codegen/validation_test.go
Expand Up @@ -71,7 +71,7 @@ var _ = Describe("validation code generation", func() {
})
})

Context("of min length 1", func() {
Context("of array min length 1", func() {
BeforeEach(func() {
attType = &design.Array{
ElemType: &design.AttributeDefinition{
Expand All @@ -85,7 +85,21 @@ var _ = Describe("validation code generation", func() {
})

It("produces the validation go code", func() {
Ω(code).Should(Equal(minLengthValCode))
Ω(code).Should(Equal(arrayMinLengthValCode))
})
})

Context("of string min length 2", func() {
BeforeEach(func() {
attType = design.String
min := 2
validation = &dslengine.ValidationDefinition{
MinLength: &min,
}
})

It("produces the validation go code", func() {
Ω(code).Should(Equal(stringMinLengthValCode))
})
})

Expand Down Expand Up @@ -227,12 +241,18 @@ const (
}
}`

minLengthValCode = ` if val != nil {
arrayMinLengthValCode = ` if val != nil {
if len(val) < 1 {
err = goa.MergeErrors(err, goa.InvalidLengthError(` + "`" + `context` + "`" + `, val, len(val), 1, true))
}
}`

stringMinLengthValCode = ` if val != nil {
if utf8.RuneCountInString(*val) < 2 {
err = goa.MergeErrors(err, goa.InvalidLengthError(` + "`" + `context` + "`" + `, *val, utf8.RuneCountInString(*val), 2, true))
}
}`

embeddedValCode = ` if val.Foo != nil {
if val.Foo.Bar != nil {
if !(*val.Foo.Bar == 1 || *val.Foo.Bar == 2 || *val.Foo.Bar == 3) {
Expand Down
3 changes: 3 additions & 0 deletions goagen/gen_app/generator.go
Expand Up @@ -122,6 +122,7 @@ func (g *Generator) generateContexts() error {
codegen.SimpleImport("strconv"),
codegen.SimpleImport("strings"),
codegen.SimpleImport("time"),
codegen.SimpleImport("unicode/utf8"),
codegen.SimpleImport("github.com/goadesign/goa"),
codegen.NewImport("uuid", "github.com/satori/go.uuid"),
}
Expand Down Expand Up @@ -355,6 +356,7 @@ func (g *Generator) generateMediaTypes() error {
codegen.SimpleImport("github.com/goadesign/goa"),
codegen.SimpleImport("fmt"),
codegen.SimpleImport("time"),
codegen.SimpleImport("unicode/utf8"),
codegen.NewImport("uuid", "github.com/satori/go.uuid"),
}
mtWr.WriteHeader(title, g.Target, imports)
Expand Down Expand Up @@ -386,6 +388,7 @@ func (g *Generator) generateUserTypes() error {
imports := []*codegen.ImportSpec{
codegen.SimpleImport("fmt"),
codegen.SimpleImport("time"),
codegen.SimpleImport("unicode/utf8"),
codegen.SimpleImport("github.com/goadesign/goa"),
codegen.NewImport("uuid", "github.com/satori/go.uuid"),
}
Expand Down
2 changes: 2 additions & 0 deletions goagen/gen_client/generator.go
Expand Up @@ -555,6 +555,7 @@ func (g *Generator) generateMediaTypes(pkgDir string, funcs template.FuncMap) er
codegen.SimpleImport("fmt"),
codegen.SimpleImport("net/http"),
codegen.SimpleImport("time"),
codegen.SimpleImport("unicode/utf8"),
codegen.NewImport("uuid", "github.com/goadesign/goa/uuid"),
}
mtWr.WriteHeader(title, g.Target, imports)
Expand Down Expand Up @@ -597,6 +598,7 @@ func (g *Generator) generateUserTypes(pkgDir string) error {
codegen.SimpleImport("fmt"),
codegen.SimpleImport("time"),
codegen.NewImport("uuid", "github.com/goadesign/goa/uuid"),
codegen.SimpleImport("unicode/utf8"),
}
utWr.WriteHeader(title, g.Target, imports)
err = g.API.IterateUserTypes(func(t *design.UserTypeDefinition) error {
Expand Down

0 comments on commit 7b80871

Please sign in to comment.