This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-12
Channels
- # admin-announcements (1)
- # bangalore-clj (13)
- # beginners (149)
- # boot (123)
- # cider (7)
- # clojure (167)
- # clojure-brasil (3)
- # clojure-greece (1)
- # clojure-korea (2)
- # clojure-new-zealand (2)
- # clojure-russia (70)
- # clojure-sanfrancisco (3)
- # clojure-spec (84)
- # clojure-uk (36)
- # clojurescript (300)
- # code-reviews (242)
- # community-development (34)
- # core-async (4)
- # css (1)
- # cursive (37)
- # datascript (1)
- # datomic (20)
- # defnpodcast (1)
- # dirac (15)
- # events (7)
- # garden (12)
- # hoplon (100)
- # lein-figwheel (11)
- # off-topic (2)
- # om (69)
- # om-next (3)
- # onyx (86)
- # planck (14)
- # proton (4)
- # protorepl (1)
- # quil (2)
- # re-frame (53)
- # rum (3)
- # untangled (1)
- # vim (50)
@agile_geek got the test working like this :
testing "get data "
(is (= {:id 1 :name "Roelof" :description "rubbish" :date "12-02-1980" :collectie nil :colors "yellow"} (api/read-data-painting {:body {:artObject {:objectNumber 1 :principalMakers [{:name "Roelof"}] :description "rubbish" :dating { :year "12-02-1980"} :collectie nil :colors "yellow"}}} ) )))
That's a good example of a test in Clojure and the process we went thru shows how you can refactor to make things easier and separate concerns.
Using the repl to poke at the data returned from API is something we do in Clojure all the time
We refactored to separate the api call (which has a side effect - an http get) from the pure function that destructures the data
making the destructure fn more testable.
yep and I can do the same for this function so I can test it :
(defn read-image-url
"Reads the image-url"
[id]
(let [art-objects (-> (str " " id "/tiles")
(client/get {:as :json :query-params {:format "json" :key (env :key)}})
:body
:levels
)
url (filter #(= (:name %) "z4") art-objects)
tiles (:tiles (first url))
image (get-in tiles [0 :url] )
]
{:id id :tiles image }))
I think this one is not testable :
(defn do-both-in-parallel
[ids]
(let [paint-thread (future (pmap #(read-data-painting (read-json-data %)) ids))
image-thread (future (pmap read-image-url ids))]
(map merge @paint-thread @image-thread)))
and I think this route file is also not testable:
(ns paintings2.routes.home
(:require [paintings2.layout :as layout]
[compojure.core :refer [defroutes GET]]
[ring.util.http-response :as response]
[ :as io]
[paintings2.api-get :as api]
[compojure.route :refer [resources]]
[environ.core :refer [env]]
[paintings2.api-get :as api]
[clj-http.client :as client]))
(defn home-page []
(let [url ""
options {:as :json :query-params {:key (env :key) :format "json" :type "schilderij" :toppieces "True"}}]
(layout/render
"home.html" {:paintings (-> (client/get url options)
api/read-numbers
api/do-both-in-parallel)})))
(defroutes home-routes
(GET "/" [] (home-page))
(resources "/") )
Can anyone help me with this problem : https://www.refheap.com/124217
You can 'integration' test the app that uses those routes by passing it a mock request constructed by this library https://github.com/ring-clojure/ring-mock but you would have to mock out the api-calls again. You could do this by wrapping your test in a with-redefs
or by injecting the api-call into the request map using a ring middleware function. Probably easier to use with-redefs
for now as the middleware option, although possibly a better solution, would take you learning more concepts.
To test your do-both-in-parallel
you could change it's arguments list to include a call-api-fn
argument (like we started doing with read-data-painting
) and use that call-api-fn
in place of the real read-json-data
. In the test pass it a fn that returns the same map using constantly
. You could give it different versions of the fn in different tests to provide different maps to test.
In the production code you would pass do-both-in-parallel
the real read-json-data
.
@rauh : I have read that part. but I do not see if the error is in the read function or the do-both-in-parallel
This line at paintings2.api_get$read_image_url.invokeStatic(api_get.clj:45)
says that your problem in in line 45 of api_get.clj
You'll need to be able to read the stacktraces, it takes some practice. It does tell you the exact line and what function it calls into
You are passing a keyword to something that is expecting a sequence (a list or vector type collection)
Oke, so I have this image-thread (future (pmap #(read-image-url (read-image-data %)) ids))]
which calls read-image-data which looks like this : `
(defn read-image-data [id] (->(str "https://www.rijksmuseum.nl/api/nl/collection/" id "/tiles")
(client/get {:as :json :query-params {:format "json" :key (env :key)}}))) `
So usually when you get an exception in clojure.core
, you look at the edge where your library FIRST calls into clojure.core. Since it's unlikely that the bug is in clojure.core π
Then check the line one above, that's the clojure.core function that is being called. That is the one you're calling incorrectly
that is here : ` at clojure.core$pmap$fn__6970$fn__6971.invoke(core.clj:6736) at clojure.core$binding_conveyor_fn$fn__4676.invoke(core.clj:1938) `
so the error is here :
at paintings2.api_get$do_both_in_parallel$fn__7399$fn__7400.invoke(api_get.clj:55)
which is this line : ' image-thread (future (pmap #(read-image-url (read-image-data %)) ids)) `
oke, then its this line : at paintings2.api_get$read_image_url.invokeStatic(api_get.clj:45)
It wanted something of type ISeq, which means something that can be passed to (seq ...)
like either a vector or a list or sequence
From the post: "As a general rule, we want to look at the deepest (earliest) point in the stacktrace that we wrote. Sometimes an error will arise from deep within a library or Clojure itselfβbut it was probably invoked by our code somewhere"
Kyle's (@aphyr) whole series 'Clojure from the ground up' is worth reading IMO
hello! I am having issue on using http kit
to start a server. I tried to start the repl, run these commands (right from the docs)
(use βorg.httpkit.server)
(defn app [req]
{:status 200
:headers {"Content-Type" "text/html"}
:body "hello HTTP!"})
(run-server app {:port 8080})
but seems that
doesnβt work, I get The localhost page isnβt working
Am I missing something or doing something wrong..?i tried a couple more time then i gave up and moved using ring
, thanks anyway @olslash π
i guess that my lack of experience on using these kind of tools doesnβt help either xD I keep hitting a lot of walls everytime i try to do something π
definitely! it takes a bit longer probably but it is so satisfying when suddenly you βsee the lightβ!
Is there a better way to say this:
(defn get-users []
(let [users (mc/find-maps db "documents")]
(map #(into {} %) (map #(seq (select-keys % [:first_name :last_name])) users))))
What are you trying to get as the result?
vector of maps
@kyle_schmidt isnβt (map #(select-keys % [:first_name :last_name]) users)
enough? (and usually favor first-name
instead of first_name
)
ahh yes, perfect!
I try to solve this puzzle : http://www.4clojure.com/problem/83
so you want to filter down to only the true ones and see if there are only 1 in that list?
I tried :
( and (not(every? true? args)) (every? true? args))) ( and (not(every? true? args)) (not-any ? true? args))) ( and (not(every? true? args)) (some true? args)))
@dpsutton : no, I try to take care if args = [ false, false, false] the outcome will be false instead of true
Hint: Switching the word "true" for "false" still gives an equivalent problem description: "Your function should return true if some of the parameters are true, but not all of the parameters are true"
fails here :
AIL in (test2) (1_half_truth_test.clj:11)
Half truth - test 2
expected: (= (half-truth true false true) true)
actual: (not (= false true))
and if I only use some it fails here :
FAIL in (test1) (1_half_truth_test.clj:7)
Half truth - test 1
expected: (= (half-truth true true true true) false)
actual: (not (= true false))
Hi everyone. Do you know if are there some tool/generator to generate test files for a project?
spec generates the boilerplate needed around the test itself, such as namespace definition, etc, etc?
no idea, I have heard of it and I have read this page : http://clojure.org/guides/spec
@marciol How do you mean "proper convention" what would you consider as a proper convention?
Seems that for the namespace hello-world
, the authors of this example created an correspondent test namespace called hello-world.service-test
but i donβt know if it is a convention of this project or if there is a broader and accepted way of organize tests
I don't think this is a clojure-wide convention. As a community, we don't have much by way of "What's best for clojure" in terms of conventions. We just think in generals "What's good for testing"
I've also seen a convention where you would name the test namespace hello-world-test
I found a really strange example of behaviour in clojure.specs
; here's how to reproduce:
(let [arst {:a [1 2 3]
:b {:c #{::z ::x ::c}}}]
(s/keys :req-un (get-in arst [:b :c])))
This spits out an AssertionError
, that tells me that all the keys must be namespace-qualified - which they are!
What is really going on here?@dominicm I tend to stick to hello-world-test
simply because a lot of tooling expects this pattern (CIDER and Porjectile for example)
@agile_geek examples using other systems were pointed at. Overall, it probably doesn't matter much.
@vandr0iy the value for :req-un must be a literal vector of namespaced keywords
not an expression that evaluates to one
@agile_geek other examples exist (and were linked). So I guess it's about the project you copy. I don't think it matters really. Just be consistent and I'll find it.
If I have this code :
(defn read-image-url
"Reads the image-url"
[response]
(let [art-objects (-> response
:body
:levels
)
id (get-in response [:body :objectNumber])
url (filter #(= (:name %) "z4") art-objects)
tiles (:tiles (first url))
image (get-in tiles [0 :url])
]
{:id id :tiles image}))
is this object right { :body {:levels {:name "z4" { [:tiles {[:url " http: //example.com ]} ]} }}
oke, I try to change a orginal response which looks like this : https://www.refheap.com/124220
What is wrong here :
"body": {
"levels": [{
"name": "z4",
"tiles": [{
url: "http: //lh6.ggpht.com/pA_7SmGBE7N60aZu5PD5emVDobNJ424v2eDWJGoZ_cDbTquRT7QukK3a4I6K-nHieHIMFBVsNiwHrJRjOAutVYiswg=s0"
}]
}]
}
does anyone happen to have a link to the in-progress clojure desk reference book?
I can't seem to scroll back that far in the #announcements history
β€οΈ u π