Skip to content

Commit

Permalink
ensure non-null values for non-nullable field types.
Browse files Browse the repository at this point in the history
  • Loading branch information
Yannick Scherer committed Mar 22, 2017
1 parent 489d9e6 commit 17f0959
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
22 changes: 20 additions & 2 deletions src/alumbra/claro/projection.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
(:require [alumbra.claro
[coercion :as c]
[values :as v]]
[claro.data :as data]
[claro.data.ops :as ops]
[claro.projection :as projection]))

Expand Down Expand Up @@ -69,16 +70,33 @@
(projection/prepare #(ops/then % coercer) projection/leaf)
projection/leaf))

(defn- nullable-value
[_ projection]
(projection/maybe projection))

(defn- non-nullable-value
[{:keys [field-name type-name]} projection]
(projection/transform
(fn [value]
(if (nil? value)
(data/error
(format "field '%s' returned 'null' but type '%s!' is non-nullable."
field-name
type-name))
value))
projection))

(defn- field-spec->projection
"Generate a projection for a `:alumbra.spec.canonical-operation/field-spec`
value."
[opts {:keys [field-type non-null? field-spec] :as spec}]
(cond->
(cond->>
(case field-type
:leaf (coerced-leaf opts spec)
:object (block->projection opts spec)
:list [(field-spec->projection opts field-spec)])
(not non-null?) projection/maybe))
(not non-null?) (nullable-value spec)
non-null? (non-nullable-value spec)))

(defn- key-for-field
"Generate the key for the given field. Will use `key-fn` to generate it
Expand Down
19 changes: 14 additions & 5 deletions test/alumbra/claro/coercion_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
(fix/schema
"enum Emotion { HAPPY HAPPIER THE_HAPPIEST }
type QueryRoot {
asId(v: ID!): ID!
asInt(v: Int!): Int!
asString(v: String!): String!
asFloat(v: Float!): Float!
asBool(v: Boolean!): Boolean!
asId(v: ID!): ID
asInt(v: Int!): Int
asString(v: String!): String
asFloat(v: Float!): Float
asBool(v: Boolean!): Boolean
asEnum(v: Emotion!): Emotion
asNonNull(v: ID!): ID!
}
schema { query: QueryRoot }"))

Expand Down Expand Up @@ -198,3 +199,11 @@
(is (= {"asId" nil} (:data result)))
(is (= "could not coerce value to 'ID': \"10\""
(-> result :errors first :message)))))

(deftest t-non-nullable-result
(let [execute! (fix/execute-fn
{:schema schema
:query {:as-non-null (->Identity nil (constantly false))}})
result (is (execute! "{ asNonNull(v: 10) }"))]
(is (= "field 'asNonNull' returned 'null' but type 'ID!' is non-nullable."
(-> result :errors first :message)))))

0 comments on commit 17f0959

Please sign in to comment.