# HG changeset patch # User Theodor Thornhill # Date 1638914757 -3600 # Tue Dec 07 23:05:57 2021 +0100 # Node ID 1f2c24075aafa0e0f426957c8222faf1e03200e8 # Parent 1a6e84bb8255215273a6f416e6ee174a3bd33d1b Resolve union members Fixes: https://todo.sr.ht/~theo/gql/29 diff --git a/src/execution.lisp b/src/execution.lisp --- a/src/execution.lisp +++ b/src/execution.lisp @@ -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 diff --git a/t/execution-tests.lisp b/t/execution-tests.lisp --- a/t/execution-tests.lisp +++ b/t/execution-tests.lisp @@ -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)