Fork me on GitHub
#test-check
<
2019-02-26
>
gfredericks01:02:41

that is super weird

borkdude07:02:44

It seems like a global thing

gfredericks12:02:40

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?

borkdude12:02:09

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

borkdude12:02:24

sorry for the confusion

gfredericks12:02:44

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

borkdude12:02:22

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)

borkdude12:02:24

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

gfredericks12:02:38

okay I think I get it

gfredericks12:02:10

I suppose that's probably good enough

gfredericks12:02:48

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

gfredericks12:02:51

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)))

borkdude12:02:32

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

borkdude12:02:17

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

gfredericks12:02:07

I don't understand that first statement

gfredericks12:02:14

how does it not work?

borkdude12:02:04

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.

gfredericks12:02:06

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

borkdude12:02:28

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

gfredericks12:02:00

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?

borkdude12:02:05

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.

gfredericks12:02:37

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

borkdude12:02:01

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

borkdude12:02:19

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

borkdude12:02:00

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.

borkdude12:02:46

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

gfredericks12:02:54

okay, I'm running such a test now

gfredericks12:02:42

(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

gfredericks12:02:18

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

borkdude12:02:17

Have you cleared the target for?

borkdude12:02:35

(Damn spelling corrector)

gfredericks12:02:08

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

gfredericks12:02:16

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

borkdude12:02:32

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

borkdude14:02:43

@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.

borkdude14:02:53

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)

gfredericks14:02:30

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

borkdude14:02:08

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

borkdude14:02:34

@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.

borkdude14:02:44

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

borkdude14:02:44

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

borkdude14:02:39

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.

gfredericks14:02:31

I just asked in #cljs-dev about this

borkdude15:02:03

ok, so it’s confirmed that this behavior exists

borkdude15:02:58

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

borkdude15:02:43

test2 would be called test_macros.cljs then

gfredericks16:02:02

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

borkdude16:02:37

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

borkdude16:02:50

but we could not reproduce this with lein cljsbuild

borkdude16:02:59

maybe that build tool has some additional magic

borkdude16:02:43

but I’m fine with your proposal

borkdude16:02:52

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

borkdude16:02:58

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

gfredericks16:02:29

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

gfredericks16:02:00

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

borkdude17:02:55

ok, will do

👍 4
borkdude17:02:34

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

gfredericks17:02:26

thanks for tracking everything down

borkdude17:02:38

New patch uploaded

gfredericks17:02:52

okay, I should get to it sometime this week

borkdude17:02:25

thanks 🙂

👍 5