test internals #7
|
@ -0,0 +1,27 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import "git.xdrm.io/go/aicra/internal/cerr"
|
||||||
|
|
||||||
|
// ErrRead - a problem ocurred when trying to read the configuration file
|
||||||
|
const ErrRead = cerr.Error("cannot read config")
|
||||||
|
|
||||||
|
// ErrFormat - a invalid format has been detected
|
||||||
|
const ErrFormat = cerr.Error("invalid config format")
|
||||||
|
|
||||||
|
// ErrIllegalServiceName - an illegal character has been found in a service name
|
||||||
|
const ErrIllegalServiceName = cerr.Error("service must not contain any slash '/' nor '-' symbols")
|
||||||
|
|
||||||
|
// ErrMissingMethodDesc - a method is missing its description
|
||||||
|
const ErrMissingMethodDesc = cerr.Error("missing method description")
|
||||||
|
|
||||||
|
// ErrMissingParamDesc - a parameter is missing its description
|
||||||
|
const ErrMissingParamDesc = cerr.Error("missing parameter description")
|
||||||
|
|
||||||
|
// ErrIllegalParamName - a parameter has an illegal name
|
||||||
|
const ErrIllegalParamName = cerr.Error("illegal parameter name (must not begin/end with '_')")
|
||||||
|
|
||||||
|
// ErrMissingParamType - a parameter has an illegal type
|
||||||
|
const ErrMissingParamType = cerr.Error("missing parameter type")
|
||||||
|
|
||||||
|
// ErrParamNameConflict - a parameter has a conflict with its name/rename field
|
||||||
|
const ErrParamNameConflict = cerr.Error("name conflict for parameter")
|
|
@ -1,7 +1,6 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,7 +9,7 @@ func (methodDef *Method) checkAndFormat(servicePath string, httpMethod string) e
|
||||||
|
|
||||||
// 1. fail on missing description
|
// 1. fail on missing description
|
||||||
if len(methodDef.Description) < 1 {
|
if len(methodDef.Description) < 1 {
|
||||||
return fmt.Errorf("missing %s.%s description", servicePath, httpMethod)
|
return ErrMissingMethodDesc.WrapString(httpMethod + " " + servicePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. stop if no parameter
|
// 2. stop if no parameter
|
||||||
|
@ -22,16 +21,16 @@ func (methodDef *Method) checkAndFormat(servicePath string, httpMethod string) e
|
||||||
// 3. for each parameter
|
// 3. for each parameter
|
||||||
for pName, pData := range methodDef.Parameters {
|
for pName, pData := range methodDef.Parameters {
|
||||||
|
|
||||||
// check name
|
// 3.1. check name
|
||||||
if strings.Trim(pName, "_") != pName {
|
if strings.Trim(pName, "_") != pName {
|
||||||
return fmt.Errorf("invalid name '%s' must not begin/end with '_'", pName)
|
return ErrIllegalParamName.WrapString(httpMethod + " " + servicePath + " {" + pName + "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pData.Rename) < 1 {
|
if len(pData.Rename) < 1 {
|
||||||
pData.Rename = pName
|
pData.Rename = pName
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Check for name/rename conflict
|
// 3.2. Check for name/rename conflict
|
||||||
for paramName, param := range methodDef.Parameters {
|
for paramName, param := range methodDef.Parameters {
|
||||||
|
|
||||||
// ignore self
|
// ignore self
|
||||||
|
@ -39,39 +38,34 @@ func (methodDef *Method) checkAndFormat(servicePath string, httpMethod string) e
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Same rename field
|
// 3.2.1. Same rename field
|
||||||
if pData.Rename == param.Rename {
|
if pData.Rename == param.Rename {
|
||||||
return fmt.Errorf("rename conflict for %s.%s parameter '%s'", servicePath, httpMethod, pData.Rename)
|
return ErrParamNameConflict.WrapString(httpMethod + " " + servicePath + " {" + pData.Rename + "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Not-renamed field matches a renamed field
|
// 3.2.2. Not-renamed field matches a renamed field
|
||||||
if pName == param.Rename {
|
if pName == param.Rename {
|
||||||
return fmt.Errorf("name conflict for %s.%s parameter '%s'", servicePath, httpMethod, pName)
|
return ErrParamNameConflict.WrapString(httpMethod + " " + servicePath + " {" + pName + "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Renamed field matches name
|
// 3.2.3. Renamed field matches name
|
||||||
if pData.Rename == paramName {
|
if pData.Rename == paramName {
|
||||||
return fmt.Errorf("name conflict for %s.%s parameter '%s'", servicePath, httpMethod, pName)
|
return ErrParamNameConflict.WrapString(httpMethod + " " + servicePath + " {" + pName + "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Manage invalid type
|
// 3.3. Fail on missing description
|
||||||
if len(pData.Type) < 1 {
|
|
||||||
return fmt.Errorf("invalid type for %s.%s parameter '%s'", servicePath, httpMethod, pName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. Fail on missing description
|
|
||||||
if len(pData.Description) < 1 {
|
if len(pData.Description) < 1 {
|
||||||
return fmt.Errorf("missing description for %s.%s parameter '%s'", servicePath, httpMethod, pName)
|
return ErrMissingParamDesc.WrapString(httpMethod + " " + servicePath + " {" + pName + "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Fail on missing type
|
// 3.4. Manage invalid type
|
||||||
if len(pData.Type) < 1 {
|
if len(pData.Type) < 1 {
|
||||||
return fmt.Errorf("missing type for %s.%s parameter '%s'", servicePath, httpMethod, pName)
|
return ErrMissingParamType.WrapString(httpMethod + " " + servicePath + " {" + pName + "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Set optional + type
|
// 3.5. Set optional + type
|
||||||
if pData.Type[0] == '?' {
|
if pData.Type[0] == '?' {
|
||||||
pData.Optional = true
|
pData.Optional = true
|
||||||
pData.Type = pData.Type[1:]
|
pData.Type = pData.Type[1:]
|
||||||
|
|
|
@ -2,20 +2,11 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.xdrm.io/go/aicra/internal/cerr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrRead - a problem ocurred when trying to read the configuration file
|
|
||||||
const ErrRead = cerr.Error("cannot read config")
|
|
||||||
|
|
||||||
// ErrFormat - a invalid format has been detected
|
|
||||||
const ErrFormat = cerr.Error("invalid config format")
|
|
||||||
|
|
||||||
// Parse builds a service from a json reader and checks for most format errors.
|
// Parse builds a service from a json reader and checks for most format errors.
|
||||||
func Parse(r io.Reader) (*Service, error) {
|
func Parse(r io.Reader) (*Service, error) {
|
||||||
receiver := &Service{}
|
receiver := &Service{}
|
||||||
|
@ -87,20 +78,20 @@ func (svc *Service) checkAndFormat(servicePath string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. stop if no child */
|
// 2. stop if no child */
|
||||||
if svc.Children == nil || len(svc.Children) < 1 {
|
if svc.Children == nil || len(svc.Children) < 1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. for each service */
|
// 3. for each service */
|
||||||
for childService, ctl := range svc.Children {
|
for childService, ctl := range svc.Children {
|
||||||
|
|
||||||
// 3. invalid name */
|
// 3.1. invalid name */
|
||||||
if strings.ContainsAny(childService, "/-") {
|
if strings.ContainsAny(childService, "/-") {
|
||||||
return fmt.Errorf("service '%s' must not contain any slash '/' nor '-' symbols", childService)
|
return ErrIllegalServiceName.WrapString(childService)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. check recursively */
|
// 3.2. check recursively */
|
||||||
err := ctl.checkAndFormat(childService)
|
err := ctl.checkAndFormat(childService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue