test-check

2019-02-26T01:40:41.001800Z

that is super weird

borkdude 2019-02-26T07:32:44.002500Z

It seems like a global thing

2019-02-26T12:18:40.003300Z

you're saying that whether or not the generators namespace wants to include macros from clojure.core determines whether or not other namespaces can implicitly include macros from generators?

borkdude 2019-02-26T12:22:09.004300Z

oh sorry, I was wrong there. I was looking for a test namespace that used gen/let in CLJS, but mistakingly pointed at the wrong line/namespace even. I’ll see if I can find a better example

borkdude 2019-02-26T12:23:24.004800Z

sorry for the confusion

2019-02-26T12:23:44.005100Z

so you're saying removing that line would allow you to write what kind of test?

borkdude 2019-02-26T12:24:22.005800Z

removing the conditional cljs portions of these require clauses in the test namespaces would enable you test if the macros work correctly in CLJS (provided they add a self-require)

borkdude 2019-02-26T12:25:24.006600Z

you were asking for a way to test this behavior: this is a way to test it. another way would be to write a completely isolated test suite

2019-02-26T12:25:38.006800Z

okay I think I get it

2019-02-26T12:26:10.007200Z

I suppose that's probably good enough

2019-02-26T12:26:48.008100Z

I can imagine somebody removing the line from src that looks redundant and then seeing the test failure and fixing it by adding :include-macros true, but that's starting to sound rather less likely

2019-02-26T12:27:51.009300Z

the thing I was imagining was something like (ns clojure.test.check.require-test (:require [clojure.test.check.generators :as gen])) (deftest can-still-use-let-without-include-macros (is (gen/let [x gen/nat] 42)))

borkdude 2019-02-26T12:28:32.009900Z

yes, but since it doesn’t seem a namespace local but a project-global inference thing, that doesn’t work if you combine it with the existing tests unchanged

borkdude 2019-02-26T12:29:17.010400Z

so adapting the existing tests to remove the :include-macros option would already be the test

2019-02-26T12:30:07.010700Z

I don't understand that first statement

2019-02-26T12:30:14.011100Z

how does it not work?

borkdude 2019-02-26T12:31:04.012100Z

ok. say you would add (ns clojure.test.check.require-test (:require [clojure.test.check.generators :as gen])) (deftest can-still-use-let-without-include-macros (is (gen/let [x gen/nat] 42))). this will already pass if clojure.test.check.generators :as gen has been required with :include-macros before.

2019-02-26T12:31:06.012200Z

I feel like I'm about to learn something terrible about clojurescript

borkdude 2019-02-26T12:31:28.012800Z

in other words: that test already passes right now, without changing anything

2019-02-26T12:32:00.013400Z

you're saying that if namespace A requires X and namespace B requires X, then what's visible from X in B is affected by how A required it?

borkdude 2019-02-26T12:33:05.014400Z

I’m not an expert in CLJS macro resolution but that’s my understanding of it. If A requires X with include-macros first, then B requires X without include-macros, it will still be able to use the macros.

2019-02-26T12:33:37.014900Z

I'm willing to bet fives of dollars that this is not true, because if it's true then I'll be so sad that I won't think to miss my fives of dollars

borkdude 2019-02-26T12:34:01.015400Z

well, it’s easy to try out. just add this test namespace of yours and run the tests.

borkdude 2019-02-26T12:35:19.016200Z

I’m not saying that I want this to be true, just that I saw this behavior when adding a similar test 🙂

borkdude 2019-02-26T12:37:00.017900Z

On the other hand, I don’t see why this would be problematic. If you don’t add :include-macros true, the worst thing that will happen is that you will get a function instead of a macro resulting in an error (the original problem), so not getting the error as a side effect of some other namespace doing the require with include-macros, is a nice bonus.

borkdude 2019-02-26T12:37:46.018300Z

@mfikes or @dnolen could maybe explain how this works in detail

2019-02-26T12:39:54.019500Z

okay, I'm running such a test now

2019-02-26T12:49:42.019900Z

(ns clojure.test.check.test2
  (:require [cljs.test :refer-macros [deftest is]]
            [clojure.test.check.generators :as gen]))

(deftest can-use-gen-let-without-include-macros
  (is (gen/let [x gen/nat] 42)))
I can't get this to fail even by removing every other test namespace

2019-02-26T12:50:18.020600Z

at first I got a compiler warning about x not being defined, which I thought was a good sign, but haven't been getting that since

borkdude 2019-02-26T12:51:17.021300Z

Have you cleared the target for?

borkdude 2019-02-26T12:51:20.021500Z

Dir

borkdude 2019-02-26T12:51:35.021900Z

(Damn spelling corrector)

2019-02-26T12:51:40.022100Z

yeah

2019-02-26T12:52:08.022500Z

and there's nothing else in the project that's requiring gen with :include-macros true

2019-02-26T12:53:16.022800Z

I just pushed this to the branch tmp-f5667927-abed-48d9-b5a8-7c7f0295b001 if you want to take a look

borkdude 2019-02-26T12:56:32.023100Z

I’ll check it out, be back in a couple of hours

borkdude 2019-02-26T14:17:43.023700Z

@gfredericks Change your test ns to something like:

(ns clojure.test.check.test2
  (:require [cljs.test :as t :refer-macros [deftest is]]
            [clojure.test.check.generators :as gen]))

(deftest can-use-gen-let-without-include-macros
  (is (gen/let [x gen/nat]
        (number? x))))

(t/run-tests)
Then I’m able to reproduce the error with:
$ clj -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "RELEASE"}}}' -m cljs.main -re node -i src/test/clojure/clojure/test/check/test2.cljs
WARNING: Use of undeclared Var clojure.test.check.test2/x at line 6 test2.cljs
WARNING: Use of undeclared Var clojure.test.check.test2/x at line 7 test2.cljs

Testing clojure.test.check.test2

ERROR in (can-use-gen-let-without-include-macros) (Error:NaN:NaN)
expected: (gen/let [x gen/nat] (number? x))
  actual: #object[Error Error: Assert failed: First arg to gen/let must be a vector of bindings.
(vector? bindings)]

Ran 1 tests containing 1 assertions.
0 failures, 1 errors.

borkdude 2019-02-26T14:19:53.025300Z

We could just write a script for this to isolate it from the rest of the tests (if you still want this tested, I think it’s pretty rare that anyone does this in a CLJS lib)

2019-02-26T14:21:30.026300Z

@borkdude But is it true that the test then passes if you revert the changes to the other test namespaces?

borkdude 2019-02-26T14:22:08.026800Z

not in this case, since I only load that one namespace here. I could test it by also loading those first

borkdude 2019-02-26T14:29:34.027400Z

@gfredericks This branch: https://github.com/borkdude/test.check/tree/tmp-f5667927-abed-48d9-b5a8-7c7f0295b001

$ clj -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "RELEASE"}}}' -m cljs.main -re node -i src/test/clojure/clojure/test/check/test2.cljs
WARNING: Use of undeclared Var clojure.test.check.test2/x at line 6 test2.cljs
WARNING: Use of undeclared Var clojure.test.check.test2/x at line 7 test2.cljs

Testing clojure.test.check.test2

ERROR in (can-use-gen-let-without-include-macros) (Error:NaN:NaN)
expected: (gen/let [x gen/nat] (number? x))
  actual: #object[Error Error: Assert failed: First arg to gen/let must be a vector of bindings.
(vector? bindings)]

Ran 1 tests containing 1 assertions.
0 failures, 1 errors.

$ clj -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "RELEASE"}}}' -m cljs.main -re node -i src/test/clojure/clojure/test/check/test.cljc -i src/test/clojure/clojure/test/check/test2.cljs
WARNING: var: clojure.test.check.generators/gen-raw-long is not public at line 158 test.cljc
WARNING: var: clojure.test.check.generators/gen-raw-long is not public at line 158 test.cljc

Testing clojure.test.check.test2

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

borkdude 2019-02-26T14:29:44.027700Z

I guess I’m pretty close to winning that 5 dollars…

borkdude 2019-02-26T14:31:44.028100Z

It seems that once the CLJS compiler knows something is a macro, it cannot unknow it?

borkdude 2019-02-26T14:36:30.028500Z

maybe that is what happens here (although that’s just me guessing): https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/analyzer.cljc#L629

borkdude 2019-02-26T14:44:39.029400Z

so when you add a self-refer to a macro in a .cljc namespace, you effectively tell the CLJS compiler: I want to use this var as macro in CLJS. Any subsequent require to that namespace does not have to help CLJS with that anymore by adding include-macros true or refer-macros, it already knows.

2019-02-26T14:56:31.029900Z

I just asked in #cljs-dev about this

borkdude 2019-02-26T15:04:03.030300Z

ok, so it’s confirmed that this behavior exists

borkdude 2019-02-26T15:09:58.031100Z

what about making a standalone script that just does this:

clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "RELEASE"}}}' -m cljs.main -re node -i src/test/clojure/clojure/test/check/test2.cljs
That wouldn’t interfere with any other namespaces requiring these macros

borkdude 2019-02-26T15:12:43.031500Z

test2 would be called test_macros.cljs then

2019-02-26T16:04:49.033600Z

Blergh

2019-02-26T16:05:02.034100Z

How about we just remove all the include-macro clauses from all src/test nses, except for the self ones

borkdude 2019-02-26T16:10:37.034800Z

yeah, that was my idea when I suggested that the tests already test this if they don’t add include-macros themselves

borkdude 2019-02-26T16:10:50.035100Z

but we could not reproduce this with lein cljsbuild

borkdude 2019-02-26T16:10:59.035400Z

maybe that build tool has some additional magic

borkdude 2019-02-26T16:11:43.035700Z

but I’m fine with your proposal

borkdude 2019-02-26T16:20:52.036100Z

I’m looking at the cljsbuild code, but it seems there is some magic around macros in there: https://github.com/emezeske/lein-cljsbuild/blob/master/support/src/cljsbuild/crossover.clj

borkdude 2019-02-26T16:22:58.036800Z

I can see why the CLJS authors ask for repros not using these tools 🙂

2019-02-26T16:53:29.037400Z

yeah I think a global policy of "no other namespace should need to require-macros from a t.c namespace because they all do self-requiring" is good enough

2019-02-26T16:54:00.038Z

so the additions to your patch would be A) deleting redundant :include-macros B) doing this trick for the prop namespace too

borkdude 2019-02-26T17:00:55.038700Z

ok, will do

👍 1
borkdude 2019-02-26T17:28:34.039500Z

also in clojure.test.check.clojure-test for defspec I presume

2019-02-26T17:41:19.039900Z

👍 yep

2019-02-26T17:41:26.040100Z

thanks for tracking everything down

borkdude 2019-02-26T17:44:38.040300Z

New patch uploaded

2019-02-26T17:47:52.040600Z

okay, I should get to it sometime this week

borkdude 2019-02-26T17:48:25.040800Z

thanks 🙂

👍 1