"errors"
"fmt"
"reflect"
- "regexp"
"strconv"
"strings"
)
-const systemKeyPattern = `^arv:[a-zA-Z]`
-
type Vocabulary struct {
reservedTagKeys map[string]bool `json:"-"`
StrictTags bool `json:"strict_tags"`
}
// Cannot have a constant map in Go, so we have to use a function.
-// If you are adding a new system property, it SHOULD match `systemKeyPattern`
-// above, and Check will allow it. This map is for historical exceptions that
+// If you are adding a new system property, it SHOULD start with `arv:`,
+// and Check will allow it. This map is for historical exceptions that
// predate standardizing on this prefix.
func (v *Vocabulary) systemTagKeys() map[string]bool {
return map[string]bool{
if v == nil {
return nil
}
- systemKeyRegexp, err := regexp.Compile(systemKeyPattern)
- if err != nil {
- return err
- }
for key, val := range data {
// Checks for key validity
- if systemKeyRegexp.MatchString(key) || v.reservedTagKeys[key] {
+ if strings.HasPrefix(key, "arv:") || v.reservedTagKeys[key] {
// Allow reserved keys to be used even if they are not defined in
// the vocabulary no matter its strictness.
continue
import (
"encoding/json"
- "fmt"
"regexp"
"strings"
c.Check(s.testVoc.Check(properties), check.IsNil)
}
-func (s *VocabularySuite) TestSystemPropertiesFirstCharacterAlphabetic(c *check.C) {
- s.testVoc.StrictTags = true
- properties := map[string]interface{}{"arv:": "value"}
- c.Check(s.testVoc.Check(properties), check.NotNil)
- // If we expand the list of allowed characters in the future, these lists
- // may need adjustment to match.
- for _, prefix := range []string{" ", ".", "_", "-", "1"} {
- for _, suffix := range []string{"", "invalid"} {
- key := fmt.Sprintf("arv:%s%s", prefix, suffix)
- properties := map[string]interface{}{key: "value"}
- c.Check(s.testVoc.Check(properties), check.NotNil)
- }
- }
-}
-
func (s *VocabularySuite) TestSystemPropertiesPrefixTypo(c *check.C) {
s.testVoc.StrictTags = true
for _, key := range []string{
+ // Extra characters in prefix
"arv :foo",
+ " arv:foo",
+ // Wrong punctuation
+ "arv.foo",
+ "arv-foo",
+ "arv_foo",
+ // Wrong case
+ "Arv:foo",
+ // Wrong word
"arvados",
"arvados:foo",
- "Arv:foo",
} {
properties := map[string]interface{}{key: "value"}
c.Check(s.testVoc.Check(properties), check.NotNil)