diff --git a/schema/ref.go b/schema/ref.go index 5ca30ec..24fd616 100644 --- a/schema/ref.go +++ b/schema/ref.go @@ -7,13 +7,15 @@ import ( // Ref holds the definition of a reference to a scope-wide object. The ref must always be inside a scope, // either directly or indirectly. If several scopes are embedded within each other, the Ref references the object -// in the current scope. +// in the scope specified. DEFAULT_NAMESPACE for current scope. type Ref interface { Object ID() string + Namespace() string Display() Display GetObject() Object + ObjectReady() bool } // NewRefSchema creates a new reference to an object in a wrapping Scope by ID. @@ -87,10 +89,18 @@ func (r *RefSchema) ReflectedType() reflect.Type { return r.referencedObjectCache.ReflectedType() } +func (r *RefSchema) ObjectReady() bool { + return r.referencedObjectCache != nil +} + func (r *RefSchema) ID() string { return r.IDValue } +func (r *RefSchema) Namespace() string { + return r.ObjectNamespace +} + func (r *RefSchema) Display() Display { return r.DisplayValue } @@ -104,8 +114,12 @@ func (r *RefSchema) ApplyScope(scope Scope, namespace string) { objects := scope.Objects() referencedObject, ok := objects[r.IDValue] if !ok { + availableObjects := "" + for objectID := range objects { + availableObjects += objectID + "\n" + } panic(BadArgumentError{ - Message: fmt.Sprintf("Referenced object '%s' not found in scope with namespace %q", r.IDValue, namespace), + Message: fmt.Sprintf("Referenced object '%s' not found in scope with namespace %q; available:\n%s", r.IDValue, namespace, availableObjects), }) } r.referencedObjectCache = referencedObject diff --git a/schema/scope_test.go b/schema/scope_test.go index e0f840a..7f8eebe 100644 --- a/schema/scope_test.go +++ b/schema/scope_test.go @@ -321,7 +321,7 @@ func TestApplyingExternalNamespace(t *testing.T) { // The applied scope must be passed down to all of those types, validating // that the scope gets applied down and that errors are propagated up. refRefSchema := schema.NewNamespacedRefSchema("scopeTestObjectB", "test-namespace", nil) - + assert.Equals(t, refRefSchema.Namespace(), "test-namespace") refProperty := schema.NewPropertySchema( refRefSchema, nil, @@ -463,7 +463,9 @@ func TestApplyingExternalNamespace(t *testing.T) { err = testData.ref.ValidateReferences() assert.Error(t, err) assert.Contains(t, err.Error(), "missing its link") + assert.Equals(t, testData.ref.ObjectReady(), false) testData.scope.ApplyScope(externalScope, "test-namespace") + assert.Equals(t, testData.ref.ObjectReady(), true) // Now it's applied, so the error should be resolved. // Outermost assert.NoError(t, testData.scope.ValidateReferences())