How to check Clojure, macro specs?
If I try to check a macro spec with clojure.spec.test.alpha, no tests are run, but if I define the same macro as a function with the same spec, a sequence of tests are run against the function. I can always generate parameters to unit test the macro, but is there a way to get that for free with spec? Here is an example:
(ns private.tmp.spec-test
(:require [clojure.spec.alpha :as spec]
[clojure.spec.test.alpha :as stest]))
;;; Macro
(defmacro twice' [x]
`(* 2.0 ~x))
(spec/fdef twice'
:args (spec/cat :x double?)
:ret double?
:fn (fn [{{:keys [x]} :args, x2 :ret}]
(or (and
(Double/isNaN x)
(Double/isNaN x2))
(= x2 (+ x x)))))
(println (stest/summarize-results (stest/check `twice'))) ;; {:total 0}
;;; Function
(defn twice [x]
(* 2.0 x))
(spec/fdef twice
:args (spec/cat :x double?)
:ret double?
:fn (fn [{{:keys [x]} :args, x2 :ret}]
(or (and
(Double/isNaN x)
(Double/isNaN x2))
(= x2 (+ x x)))))
(println (stest/summarize-results (stest/check `twice))) ;; {:total 1, :check-passed 1}
See also questions close to this topic
-
clojure/lein repl does not work with all database loaded
I have used
lien repl
commond to test some operation on the database of my project. But I was not able to connect to it.Then I found that the issue is database was not getting loaded. The only solution i was able to try out was:
lein run
this resulted in following messages:
2018-04-24 12:23:07,397 [main] INFO guestbook.core - #'guestbook.db.core/*db* started 2018-04-24 12:23:07,398 [main] INFO guestbook.core - #'guestbook.handler/init-app started 2018-04-24 12:23:07,398 [main] INFO guestbook.core - #'guestbook.handler/app started 2018-04-24 12:23:07,398 [main] INFO guestbook.core - #'guestbook.core/http-server started 2018-04-24 12:23:07,398 [main] INFO guestbook.core - #'guestbook.core/repl-server started
then I ran the following command :
lein repl :connect 7000 this connected to database and started repl. next commands worked fine: user=> (use 'guestbook.db.core) nil user=> (get-messages) nil
Please let me know if there is any other way too?
-
nginx prod setup for Clojure WebSocket app
I'm trying to deploy my first Clojure WebSocket app and I think I'm getting close. I get a good response locally, and it looks like the endpoint wants to face the outside world (I see that the port is open when I run
netstat
), but no response. I'm certain that I have something setup incorrectly innginx
.I currently already host a few other websites on this server, just want to add the necessary config to get requests made to
wss://domain.com:8001
to communicate with my app.Here is the location entry I'm using now:
location / { proxy_pass http://localhost:8001; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect off; access_log /var/www/logs/test.access.log; error_log /var/www/logs/test.error.log; }
Could anyone help point me in the right direction? My guess is that I actually have too much in the config, and what's there is probably not correct.
** EDIT: ** For interested parties, I put up my working config (based on Erik Dannenberg's answer) in a gist.
-
Clojure app running only in tcp6
So I'm in over my head, but I nearly have a working Clojure app with WebSocket connection deployed to a prod-like environment, but there are a few things that I can't seem to work out. When I hit the endpoint with
curl
fromlocalhost
I get the response I was hoping for, so far so good. But when I try access it from my domain, I don't get a connection. When I checkednetstat
to make sure the port (8001
) is open, I see the following:Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3283/nginx: master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3218/sshd tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 3283/nginx: master tcp6 0 0 :::8001 :::* LISTEN 3260/java tcp6 0 0 :::80 :::* LISTEN 3283/nginx: master tcp6 0 0 :::22 :::* LISTEN 3218/sshd tcp6 0 0 :::443 :::* LISTEN 3283/nginx: master
I am running
ufw
but I alreadyallow
ed the port, so I'm not sure if there is something I need to do when running the app to make it available as a normaltcp
service? Or am I barking up the wrong tree?Here is the command that is currently running:
java -jar test.jar 8001
Also I was torn between here and serverfault, but opted for stackoverflow because I think it's Clojure-centric. Please feel free to correct me.
-
C++: Can a macro argument have a space in it?
If I define a macro taking argument as below.
#define define_int(a) int a;
And provide an argument with space in between like below
define_int(* a)
and get output?
int * a;
Intended use
#define ASSIGN(A,B) B=A;
I want to return from a function directly using this macro as
ASSIGN(A, return B)
so that it would output,
return B = A;
-
How to copy data from one sheet to another when modified in excel using macros
Currently I am working in excel i need a vba script like whenever i modify a data a new sheet should generate with the modified username can some one help me on this?
-
C macro function has the same output of equivalent normal function, but the algorithm has a different output
So I've got a function that has the same definition as a macro function, and they output the same value. To confirm this, I did this:
int a(int vertex, int offset) { int value = vertex*numberOfoffsets + offset; if (value != b(vertex, offset)) printf("error\n"); return value; }
Here's the macro:
#define b(vertex, offset) (vertex*numberOfoffsets + offset) //EDIT: I had mta instead of b here (on the stackoverflow post)
Note that
numberOfOffsets
is also a macro itself, which returns 6. I ran the algorithm usinga(vertex,offset)
and everything works as expected, with noerror\n
printed, which means both functions return the same value.But when I run the algorithm with
b(vertex,offset)
instead ofa(vertex,offset)
, a wrong answer comes out (although the algorithm doesn't break.Is there anything that I'm missing regarding macros? Don't they just replace text? I don't really understand this behavior.
EDIT: Sorry I forgot to change the name of the fuction, b is now correct (it's the define function)
EDIT2: Adding parentheses fixes the problem, so it should be:
#define b(vertex, offset) (((vertex)*(numberOfoffsets)) + (offset))
But other users suggested that I used inline functions instead, so now it's:
static __inline__ int b(int vertex, int offset) { return vertex*numberOfoffsets + offset; }
-
How to always generate data for optional keys in a spec?
If I have a spec like
(clojure.spec/def ::person (clojure.spec/keys :req [::name ::address] :opt [::age]))
And when I do
(clojure.spec.gen/generate (clojure.spec/gen ::person))
Is there any way to tell the generator to always consider the optional key(s) when generating data for it?
I know that this could be done with custom generators but I wanted to know if there is a functionality already available for it or maybe a simpler approach which does not involve me defining a custom generator.
-
How do you use "fdef" with maps in parameters?
I'm trying to get fdef to successfully validate with a collection of maps as a parameter. I'm getting the following:
(defn func [foo bar]) (def t [{:a "hi ":b "jimbob"} {:a "hi" :b "johnboy"}]) (spec/def ::a string?) (spec/def ::b string?) (spec/def ::c string?) (spec/def ::d string?) (spec/fdef func :args (spec/cat :foo string? :bar (spec/+ (spec/keys :req-un [::a ::b] :opt-un [::c ::d])))) (stest/instrument) (func "hello" t) => #'dmp-onboarding-service.handler/func => #'dmp-onboarding-service.handler/t => :dmp-onboarding-service.handler/a => :dmp-onboarding-service.handler/b => :dmp-onboarding-service.handler/c => :dmp-onboarding-service.handler/d => dmp-onboarding-service.handler/func => [dmp-onboarding-service.handler/send-email! dmp-onboarding-service.handler/func user/test] ExceptionInfo Call to #'dmp-onboarding-service.handler/func did not conform to spec: In: [1] val: [{:a "hi ", :b "jimbob"} {:a "hi", :b "johnboy"}] fails at: [:args :bar] predicate: map? clojure.core/ex-info (core.clj:4739)
Clearly I'm missing how to couple args with their spec; this works:
(spec/explain string? "hello") Success! => nil
As does this
(spec/explain (spec/+ (spec/keys :req-un [::a ::b] :opt-un [::c ::d])) [{:a "hi ":b "jimbob"} {:a "hi" :b "johnboy"}]) Success! => nil
Any help is much appreciated!
-
Compare between two specs values, Clojure.spec
I have defined specs as -
(s/def ::start integer?) (s/def ::end integer?) (s/def ::collection (s/keys :req-un [::start ::end]))
It is working fine as
(s/valid? ::collection {:start 9 :end 13})
But now I also have to check that
start
should be less thanend
. How to do that? Is there a simpler way to do that without creating an another fn and check? -
Why is my Scalacheck test with a custom Generator failing after discarding many cases, and how do I fix this?
I am a newbie with Scala and I am writing my first Scalacheck suite.
I have a data structure in my program that essentially looks like a
(List[Double], List[Double])
which is well-formed only if each element of_1
is strictly greater than the corresponding element of_2
.Since it's slightly more complicated in practice (although for the purpose of this MWE we can pretend there's all there is to it), I've written a custom generator for it.
I then added two trivial tests (including the most trivial of all,
1 == 1
) and in both cases the tests fail, with the messageGave up after only XX passed tests. YYY tests were discarded.
Why is it, and how do I fix it?
Attached is my test suite and the output.
package com.foo.bar import org.scalacheck._ import Prop._ import Arbitrary._ object FooSpecification extends Properties("FooIntervals") { type FooIntervals = (List[Double], List[Double]) /* This is supposed to be a tuple of lists s.t. each element of _1 * is < the corresponding element of _2 * * e.g. (List(1,3,5), List(2,4,6)) */ implicit def arbInterval : Arbitrary[FooIntervals] = Arbitrary { /** * Yields a pair (low, high) s.t. low < high */ def GenPair : Gen[(Double, Double)] = for { low <- arbitrary[Double] high <- arbitrary[Double].suchThat(_ > low) } yield (low, high) /** * Yields (List(x_1,...,x_n), List(y_1,...,y_n)) * where x_i < y_i forall i and 1 <= n < 20 */ for { n <- Gen.choose(1,20) pairs : List[(Double, Double)] <- Gen.containerOfN[List, (Double, Double)](n, GenPair) } yield ((pairs.unzip._1, pairs.unzip._2)) } property("1 == 1") = forAll { (b1: FooIntervals) => 1 == 1 } property("_1.head < _2.head") = forAll { (b1: FooIntervals) => b1._1.head < b1._2.head } }
[info] ! FooIntervals.1 == 1: Gave up after only 32 passed tests. 501 tests were discarded. [info] ! FooIntervals._1.head < _2.head: Gave up after only 28 passed tests. 501 tests were discarded. [info] ScalaTest [info] Run completed in 1 second, 519 milliseconds. [info] Total number of tests run: 0 [info] Suites: completed 0, aborted 0 [info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0 [info] No tests were executed. [error] Failed: Total 1, Failed 1, Errors 0, Passed 0 [error] Failed tests: [error] com.foo.bar.FooSpecification
-
What is generative testing in Clojure?
I came across
Generative Testing in Clojure with spec
notion and would like to learn about it.Also providing some examples would be very useful.