Skip to content

Commit

Permalink
Add proper method to access root object
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredoconnell committed Apr 18, 2024
1 parent 2451781 commit 4d8c2ef
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 9 deletions.
51 changes: 42 additions & 9 deletions schema/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type Scope interface {
Object
Objects() map[string]*ObjectSchema
Root() string
RootObject() *ObjectSchema

SelfSerialize() (any, error)
}
Expand Down Expand Up @@ -56,40 +57,40 @@ func (s *ScopeSchema) SelfSerialize() (any, error) {
}

func (s *ScopeSchema) ID() string {
return s.ObjectsValue[s.RootValue].ID()
return s.RootObject().ID()
}

func (s *ScopeSchema) Properties() map[string]*PropertySchema {
return s.ObjectsValue[s.RootValue].PropertiesValue
return s.RootObject().PropertiesValue
}

func (s *ScopeSchema) GetDefaults() map[string]any {
return s.ObjectsValue[s.RootValue].GetDefaults()
return s.RootObject().GetDefaults()
}

func (s *ScopeSchema) ReflectedType() reflect.Type {
return s.ObjectsValue[s.RootValue].ReflectedType()
return s.RootObject().ReflectedType()
}

func (s *ScopeSchema) Unserialize(data any) (any, error) {
return s.ObjectsValue[s.RootValue].Unserialize(data)
return s.RootObject().Unserialize(data)
}

func (s *ScopeSchema) ValidateCompatibility(typeOrData any) error {
schemaType, ok := typeOrData.(*ScopeSchema)
if ok {
return s.ObjectsValue[s.RootValue].ValidateCompatibility(schemaType.ObjectsValue[schemaType.RootValue])
return s.RootObject().ValidateCompatibility(schemaType.ObjectsValue[schemaType.RootValue])
}

return s.ObjectsValue[s.RootValue].ValidateCompatibility(typeOrData)
return s.RootObject().ValidateCompatibility(typeOrData)
}

func (s *ScopeSchema) Validate(data any) error {
return s.ObjectsValue[s.RootValue].Validate(data)
return s.RootObject().Validate(data)
}

func (s *ScopeSchema) Serialize(data any) (any, error) {
return s.ObjectsValue[s.RootValue].Serialize(data)
return s.RootObject().Serialize(data)
}

func (s *ScopeSchema) ApplyScope(externalScope Scope, namespace string) {
Expand Down Expand Up @@ -123,6 +124,38 @@ func (s *ScopeSchema) Objects() map[string]*ObjectSchema {
return s.ObjectsValue
}

func (s *ScopeSchema) objectIDList() string {
output := ""
for id := range s.ObjectsValue {
output += "\n" + id
}
return output
}

func (s *ScopeSchema) RootObject() *ObjectSchema {
rootObject, rootObjectFound := s.ObjectsValue[s.RootValue]
if !rootObjectFound {
panic(fmt.Sprintf(
"root object with ID %q not found; available objects:%s",
s.RootValue,
s.objectIDList(),
))
}
if rootObject == nil {
panic(fmt.Sprintf(
"root object with ID %q is nil; this is a bug",
s.RootValue,
))
}
if rootObject.ID() != s.RootValue {
panic(fmt.Sprintf(
"root object's ID %q doesn't match its map key %q; please fix the input",
rootObject.ID(), s.RootValue,
))
}
return rootObject
}

func (s *ScopeSchema) Root() string {
return s.RootValue
}
Expand Down
39 changes: 39 additions & 0 deletions schema/scope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,3 +498,42 @@ func TestApplyingExternalNamespaceToNonRefTypes(t *testing.T) {
})
}
}

func TestMismatchedRoot(t *testing.T) {
// This is a common user mistake: invalid root key
brokenSchema := schema.ScopeSchema{
ObjectsValue: map[string]*schema.ObjectSchema{
"a": schema.NewObjectSchema("a", map[string]*schema.PropertySchema{}),
},
RootValue: "wrong",
}
assert.PanicsContains(t, func() {
brokenSchema.RootObject()
}, "root object with ID \"wrong\" not found; available objects:\na")
}

func TestNilRoot(t *testing.T) {
// This is just a bug case
brokenSchema := schema.ScopeSchema{
ObjectsValue: map[string]*schema.ObjectSchema{
"a": nil,
},
RootValue: "a",
}
assert.PanicsContains(t, func() {
brokenSchema.RootObject()
}, "root object with ID \"a\" is nil")
}

func TestMismatchedRootID(t *testing.T) {
// This is a common user mistake: valid key doesn't match object ID
brokenSchema := schema.ScopeSchema{
ObjectsValue: map[string]*schema.ObjectSchema{
"a": schema.NewObjectSchema("wrong", map[string]*schema.PropertySchema{}),
},
RootValue: "a",
}
assert.PanicsContains(t, func() {
brokenSchema.RootObject()
}, "root object's ID \"wrong\" doesn't match its map key \"a\"")
}

0 comments on commit 4d8c2ef

Please sign in to comment.