M src/execution.lisp +8 -6
@@ 259,13 259,15 @@
(defun resolve-abstract-type (abstract-type object-value)
;; TODO: https://spec.graphql.org/draft/#ResolveAbstractType()
- ;; TODO: #29
(check-type object-value gql-object)
- (etypecase abstract-type
- (interface-type-definition
- ;; TODO: Should this error handle somehow?
- (gethash (type-name object-value) *all-types*))
- (union-type-definition nil)))
+ (let* ((type-name (type-name object-value))
+ (object-definition (gethash type-name *all-types*)))
+ (etypecase abstract-type
+ (interface-type-definition object-definition)
+ (union-type-definition
+ (let ((union-member
+ (find type-name (union-members abstract-type) :key #'nameof :test #'string=)))
+ (gethash (nameof union-member) *all-types*))))))
(defun execute-field (object-type object-value field-type fields variable-values)
;; TODO: https://spec.graphql.org/draft/#sec-Executing-Fields
M t/execution-tests.lisp +46 -0
@@ 216,6 216,52 @@
(command (gethash "doesKnowCommand" dog)))
(ok (string= command "false")))))))
+(deftest abstract-type-resolvers
+ (testing "Getting object-type-definition from union or interface"
+ (defclass pet (gql-object)
+ ((name :initarg :name :accessor name)))
+
+ (defclass dog (pet)
+ ((owner :initarg :owner :accessor owner)
+ (nickname :initarg :nickname :accessor nickname)))
+
+ (defclass cat (pet)
+ ((nickname :initarg :nickname :accessor nickname)))
+
+ (defclass sentient (gql-object)
+ ((name :initarg :name :accessor name)))
+
+ (defclass human (sentient)
+ ((pets :initarg :pets :accessor pets)))
+
+ (defparameter *doggo*
+ (make-instance
+ 'dog
+ :name "Bingo-Bongo"
+ :type-name "Dog"
+ :nickname "Hund!"
+ :owner (make-instance
+ 'human
+ :name "Wingle Wangle"
+ :type-name "Human"
+ :pets `(,(make-instance
+ 'dog
+ :name "Bingo-Bongo"
+ :nickname "Hund!"
+ :type-name "Dog")
+ ,(make-instance
+ 'cat
+ :name "Bango-Wango"
+ :nickname "Mjausig"
+ :type-name "Cat")))))
+
+ (with-schema (build-schema (asdf:system-relative-pathname 'gql-tests #p"t/test-files/validation-schema.graphql"))
+ ;; We want to know if we did get the actual same reference.
+ (ok (eq (gql::resolve-abstract-type (gethash "CatOrDog" gql::*all-types*) *doggo*)
+ (gethash "Dog" gql::*all-types*)))
+ (ok (eq (gql::resolve-abstract-type (gethash "Pet" gql::*all-types*) *doggo*)
+ (gethash "Dog" gql::*all-types*))))))
+
(deftest doggo-test
(testing "Doggo-testing"
(defclass pet (gql-object)