Skip to content

Commit

Permalink
Fix #138. Allow decisions to return functions
Browse files Browse the repository at this point in the history
If a decision returns a function which is expected to take no arguments
then the function's return value is used as the updated context.

This allows to circumvent the deep merge of maps and lists which context
updates do by default.
  • Loading branch information
ordnungswidrig committed Jul 3, 2014
1 parent 5234302 commit 46fb458
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
7 changes: 7 additions & 0 deletions CHANGES.markdown
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

# New in 0.11.1

## Bugs fixed

* #138 context update deeply merges values. Support workaround
by enabling to evaluate a returned 0-ary function

# New in 0.11.0

* #97 Adds support for a default resource definition map parameter
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject liberator "0.11.0"
(defproject liberator "0.11.1"
:description "Liberator - A REST library for Clojure."
:dependencies [[org.clojure/clojure "1.4.0"]
[org.clojure/tools.trace "0.7.3"]
Expand Down
11 changes: 8 additions & 3 deletions src/liberator/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,22 @@
(and (vector? curr) (vector? newval)) (vec (concat curr newval))
:otherwise newval))

(defn update-context [context context-update]
(cond
(map? context-update) (combine context context-update)
(fn? context-update) (context-update)
:otherwise context))

(defn decide [name test then else {:keys [resource request] :as context}]
(if (or (fn? test) (contains? resource name))
(if (or (fn? test) (contains? resource name))
(let [ftest (or (resource name) test)
ftest (make-function ftest)
fthen (make-function then)
felse (make-function else)
decision (ftest context)
result (if (vector? decision) (first decision) decision)
context-update (if (vector? decision) (second decision) decision)
context (if (map? context-update)
(combine context context-update) context)]
context (update-context context context-update)]
(log! :decision name decision)
((if result fthen felse) context))
{:status 500 :body (str "No handler found for key \"" name "\"."
Expand Down
14 changes: 13 additions & 1 deletion test/test_execution_model.clj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,19 @@
(-> (request :get "/")
((resource :exists? [true {:a 1}]
:handle-ok #(ring-response %))))
=> (contains {:a 1 :status 200})))
=> (contains {:a 1 :status 200}))
(fact "vector concated to context value"
(-> (request :get "/")
((resource :service-available? {:a [1]}
:exists? {:a [2]}
:handle-ok #(ring-response %))))
=> (contains {:a [1 2] :status 200}))
(fact "function returned as context is evaluated"
(-> (request :get "/")
((resource :service-available? {:a [1]}
:exists? (fn [ctx] #(assoc ctx :a [2]))
:handle-ok #(ring-response %))))
=> (contains {:a [2] :status 200})))

(facts "falsey return values"
(fact (-> (request :get "/")
Expand Down

0 comments on commit 46fb458

Please sign in to comment.