Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add proper method to access scope root object #85

Merged
merged 5 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(separator string) string {
output := ""
for id := range s.ObjectsValue {
output += separator + 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("\n\t"),
))
}
if rootObject == nil {
panic(fmt.Sprintf(
"root object with ID %q is nil",
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,
))
}
webbnh marked this conversation as resolved.
Show resolved Hide resolved
return rootObject
}

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

func TestGetRootObject(t *testing.T) {
rootObject := schema.NewObjectSchema("a", map[string]*schema.PropertySchema{})
correctSchema := schema.ScopeSchema{
ObjectsValue: map[string]*schema.ObjectSchema{
"a": rootObject,
},
RootValue: "a",
}
assert.Equals(t, correctSchema.RootObject(), rootObject)
}

func TestMismatchedRoot(t *testing.T) {
dbutenhof marked this conversation as resolved.
Show resolved Hide resolved
// This is a common user mistake: invalid RootValue in the scope.
// Panic when a Scope's RootValue is not a key in its ObjectsValue
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:\n\ta")
}

func TestNilRoot(t *testing.T) {
// This is just a bug case; nil object in the objects map.
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 scope map key doesn't match the object's ID
brokenSchema := schema.ScopeSchema{
ObjectsValue: map[string]*schema.ObjectSchema{
"wrong": schema.NewObjectSchema("a", map[string]*schema.PropertySchema{}),
},
RootValue: "wrong",
}
webbnh marked this conversation as resolved.
Show resolved Hide resolved
assert.PanicsContains(t, func() {
brokenSchema.RootObject()
}, "root object's ID \"a\" doesn't match its map key \"wrong\"")
}
webbnh marked this conversation as resolved.
Show resolved Hide resolved